Julien Posted July 30, 2020 Report Share Posted July 30, 2020 Hi, I recently experienced an issue related to the static sc_vpool objects used in some classes in the SystemC kernel. Here is an example: #include <systemc.h> class Dummy { public: Dummy(int a) { sc_int<32> my_int(a); my_int(2,1); } }; Dummy dummy(12); int sc_main(int argc , char *argv[]) { return 0; } This program crashes at startup with the following stack trace: #0 0x0000000000404e66 in sc_dt::sc_int_subref_r::initialize (this=0x0, obj_p=0x7fffffffdde0, left_i=2, right_i=1) at /remote/vgrnd104/julient/OSCI/linux/systemc-2.3.3/include/sysc/datatypes/int/sc_int_base.h:338 #1 0x0000000000405102 in sc_dt::sc_int_base::operator() (this=0x7fffffffdde0, left=2, right=1) at /remote/vgrnd104/julient/OSCI/linux/systemc-2.3.3/include/sysc/datatypes/int/sc_int_base.h:1282 #2 0x000000000040513f in Dummy::Dummy (this=0x701b11 <dummy>, a=12) at test.cpp:7 #3 0x0000000000404d81 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at test.cpp:11 #4 0x0000000000404d97 in _GLOBAL__sub_I_dummy () at test.cpp:15 #5 0x00000000004c623d in __libc_csu_init () #6 0x00007ffff702ecb0 in __libc_start_main () from /lib64/libc.so.6 #7 0x0000000000404c29 in _start () Note that the example only crashes when it is statically linked to the SystemC library. It does not crash when it is dynamically linked to the SystemC library. This crash is caused by a wrong order of initialization of the static and global objects: - The dummy global variable is initialized first. - The constructor of Dummy calls sc_int_base::operator() which uses the static sc_int_subref::m_pool object (sc_int_base.h line 1281). - But m_pool has not yet been created. This leads to the crash. So this crash is a typical static initialization order fiasco situation. However, the above example is very simple and does nothing uncommon. And the crash is related to an internal implementation of the SystemC kernel. So it is very hard for the SystemC user to understand why his program crashes and why he should change his code to make it work. So I would suggest to change the internal implementation to avoid using static sc_vpool objects. Current implementation: sc_int_base.h line 527: static sc_core::sc_vpool<sc_int_subref> m_pool; sc_int_base.h line 1281: sc_int_subref* result_p = sc_int_subref::m_pool.allocate(); Maybe I'm missing something, but the following might be a possible new implementation: sc_int_base.h line 527: static sc_core::sc_vpool<sc_int_subref>& pool() { static sc_core::sc_vpool<sc_int_subref> subref_pool; return subref_pool; } sc_int_base.h line 1281: sc_int_subref* result_p = sc_int_subref::pool().allocate(); Similar changes should be done for all the static sc_vpool objects. Thus, static sc_vpool objects would not be necessary anymore, and this would avoid this crash. Any opinion about that? Thanks. Julien Quote Link to comment Share on other sites More sharing options...
Julien Posted August 11, 2020 Author Report Share Posted August 11, 2020 Any comment about this issue? The issue seems to be related to the internal implementation of the SystemC kernel. So if possible, I would appreciate to get the opinion of the systemC experts about it. Thanks. Julien Quote Link to comment Share on other sites More sharing options...
maehne Posted September 21, 2020 Report Share Posted September 21, 2020 Dear Julien, thanks for reporting that issue! I confirm your findings and have forwarded the issue to the SystemC LWG so that it can be fixed. I am sorry for the long delay reacting to your message due to the summer vacation period. Best regards, Torsten Maehne Quote Link to comment Share on other sites More sharing options...
Julien Posted September 21, 2020 Author Report Share Posted September 21, 2020 Hi Torsten, Thanks for the confirmation of the issue. Regards, Julien Quote Link to comment Share on other sites More sharing options...
Andy Goodrich Posted January 27, 2021 Report Share Posted January 27, 2021 It bothers me a bit that we got all the way to sc_int_subref_r::initialize() with a NULL this pointer, rather than having things die in sc_vpool::allocate(). If hoisting the sc_vpool object so that the static initialization is within a method is the way to go I would prefer to place things where the invocation is made: sc_int_subref& operator() ( int left, int right ) { static sc_vpool<sc_int_subref> pool(9); sc_int_subref* result_p = pool.allocate(); result_p->initialize( this, left, right ); return *result_p; } Quote Link to comment Share on other sites More sharing options...
Andy Goodrich Posted January 27, 2021 Report Share Posted January 27, 2021 But let me think about it as we have multiple uses... Quote Link to comment Share on other sites More sharing options...
maehne Posted January 27, 2021 Report Share Posted January 27, 2021 Thanks @Andy Goodrich for your additional analysis. We probably should also take into account the recent feedback from @Runip Gopisetty on the datatypes, where he also mentioned the sc_vpool objects as being problematic making the SystemC datatypes not thread-safe. Quote Link to comment Share on other sites More sharing options...
Andy Goodrich Posted January 27, 2021 Report Share Posted January 27, 2021 I will try an implementation along the lines of: sc_int_subref* temporary_subref() { static sc_vpool<sc_int_subref> pool(9); return pool.allocate(); } sc_int_subref& operator() ( int left, int right ) { sc_int_subref* result_p = temporary_subref(); result_p->initialize( this, left, right ); return *result_p; } Quote Link to comment Share on other sites More sharing options...
Andy Goodrich Posted January 27, 2021 Report Share Posted January 27, 2021 I am assuming his issue is the use of static storage members, whether those members are static class members, or storage within a method/function? If so, things gets a bit ugly, as we need to generate values that are persistent for at least the life of concatenations. Quote Link to comment Share on other sites More sharing options...
Andy Goodrich Posted January 27, 2021 Report Share Posted January 27, 2021 I do have a scheme that should work for that case, but it will definitely tie datatypes to the sc_simcontext instance, so it conflicts with requests to separate data types from the rest of the simulator. Quote Link to comment Share on other sites More sharing options...
TTT Posted June 14, 2021 Report Share Posted June 14, 2021 (edited) Hi, any updates to this topic ? I recently faced the same globals in memory leak detectors reports (valgrind on Linux and crtdbg on Windows) when only adding static linkage to systemc. update: I found SYSTEMC_MEMPOOL_DONT_USE=1 from other posts for suppressing it. But still interested as most recent posts here refer to potential other solution being considered. Edited June 14, 2021 by TTT Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.