Jump to content

Recommended Posts

Posted

Hi,

 

I have a strange problem and i think i have root-caused it. I wanted to shared that in the Forum an solicit suggestions.

 

I have a SystemC module A and B implemented in libA.so  and libB.so file. I also have a test-bench.exe file that load (explicit DLL load) these components and connect them. Component A add an extension (lets name it ext_t) to the TLM that it transacts with component B. And B is suppose to consume this extension. In addition, A as well as B may add addition (non-shared) extension to the payload. (say a_specific_ext_t and b_specific_ext_t respectively)

 

I noticed that the component B was not able to extract the extension ext_t. The solution works when i compile the A, B and the executable into a single executable.

 

I think, the TLM extension is not guaranteed to work across DLL, for explicit DLL load ones. B/c the TLM extension uses the technique of mapping a extension type to an integer. This integer is used to index into the extension array. When the components are implemented across .so file, One need to ensure that the extension in different .so map to same index. Hence, the order or of "extending" should match.

 

Have you guys observed this in your setup. Any suggestion to solve this issue?

 

One thing i thought was to have a third .so file called libextension_super_set.so. This .so file will extend all the possible TLM extension that the components want to exchange. And each of these components shall implicitly link against this .so and hence the index uniqueness is guaranteed to work. I have not tried this one. 

 

BR/Nizamudheen Ahmed

 

Posted

Nizamudheen,

 

your analysis is correct.  You've implicitly entered C++'s undefined behaviour land by adding several copies of the following function (including its local static variable) to your final executable, one from each .so file using TLM extensions:

 

// Helper function:
inline unsigned int max_num_extensions(bool increment=false)
{
    static unsigned int max_num = 0;
    if (increment) ++max_num;
    return max_num;
}

The proposed solution to move the implementation of all extensions to a common base library may help.  But this will still heavily depend on your C++ toolchain/implementation.

 

The "correct" solution would be to move the implementation of (at least) the function above itself to an .so file.

 

Sometime last year, we have briefly discussed in the LWG to start moving parts of the TLM implementation from the headers to the (SystemC) pre-built library.  This would help to solve this issue as well.  In fact, your use case is a strong motivation for this.

 

Greetings from Oldenburg,

  Philipp

Posted

Thanks Philip for your detailed answer

 

I see 2 different problems here/

 

1. Across .so files, the indexes assigned to each extension should be unique

2. Across .so files the indexes assigned to same extension (say a type ext_1_t is extended in different .so files) should be same.

 

 

I can see that the item 1 shall be solved by moving max_num_extensions to systemc.so file. Do you see that itme2 shall also be resolved with the same fix?

 

BR/Nizamudheen Ahmed

Posted

Nizamudheen,

 

generally speaking, the second case should be solved by suggested fix as well.  On the other hand, when you duplicate classes/functions (with global/static variables) in several .so files, there be dragons.

 

In order to avoid symbol duplication (and therefore the risk of chosing the "wrong" implementation after loading the .so files), you should move shared extensions to common libraries as well.

 

As I said, this holds for all class/function duplicates across .so files.  You shall not use global/static variables in such cases, as the toolchain/implementation is not required to diagnose these kind of errors (see One Definition Rule).

 

Greetings from Oldenburg,

  Philipp

Posted

Hi Philip,

 

Thanks for the response. Actually, i tried to reproduce the fix (you suggested) in a simple C++ environment. And, as i suspected, the item # 2 in my earlier mail is not covered with the fix. I have attached a simple package that demonstrates this. Can you take a look at it and correct me if i overlooked at something?

 

If needed, i can call you and talk about this issue.

 

 

Thanks a lot, in advance.

 

BR/Nizamudheen Ahmed

test.tar.gz

Posted

Nizamudheen,

 

your example works as expected on my Debian GNU/Linux system:

EXT_A:1
EXT_B:2
EXT_B:2
EXT_A:1

As you can see, both extensions have the same ID across both libraries, which is what I would expect.

 

I suspect that on your platform/toolchain the symbol resolution and initialization is different, especially for the implicitly loaded library libsc.so.  You need to consult the corresponding documentation for more information, maybe you need to use RTLD_NOW and RTDL_GLOBAL (or equivalents) to properly initialize the extension libraries. 

 

Greetings from Oldenburg,
  Philipp

Posted

Hi Philip,

 

With RTLD_NOW | RTLD_GLOBAL flags to dlopen, i found that i don't have to move the max_num_extensions to .so file. It works well even if i have it in the header file.

 

BR/Nizamudheen

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...