-
Notifications
You must be signed in to change notification settings - Fork 481
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Profiling capabilities #15
Labels
type:feature
new or enhanced functionality
Comments
Closed
Profiled the endian_swapper example from changeset 89d892c with percall values removed for clarity since they are all 0.00
|
Endian swapper example makefile now has a "profile" target that will generate an SVG callgraph. |
imphil
added a commit
to imphil/cocotb
that referenced
this issue
Oct 12, 2022
cocotb crashes when running the mixed language example with Riviera-PRO, using a Verilog toplevel and the pre-built binary wheels (manylinux2014, built on CentOS7). Valgrind reports ``` COUT: ==6174== Invalid free() / delete / delete[] / realloc() COUT: ==6174== at 0xC78271B: operator delete(void*) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) COUT: ==6174== by 0x1CE1AC80: std::string::assign(std::string const&) (in /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib/python3.10/site-packages/cocotb/libs/libgpilog.so) COUT: ==6174== by 0x1CDE56C6: GpiObjHdl::initialise(std::string const&, std::string const&) (GpiCbHdl.cpp:74) COUT: ==6174== by 0x1CE3D587: VhpiObjHdl::initialise(std::string const&, std::string const&) (VhpiCbHdl.cpp:258) COUT: ==6174== by 0x1CE46932: VhpiImpl::create_gpi_obj_from_handle(unsigned int*, std::string&, std::string&) (VhpiImpl.cpp:462) COUT: ==6174== by 0x1CE470E5: VhpiImpl::native_check_create(std::string&, GpiObjHdl*) (VhpiImpl.cpp:575) COUT: ==6174== by 0x1CDE6E1E: gpi_get_handle_by_name_(GpiObjHdl*, std::string, GpiImplInterface*) (GpiCommon.cpp:297) COUT: ==6174== by 0x1CDE711C: gpi_get_handle_by_name (GpiCommon.cpp:339) COUT: ==6174== by 0x14BF9595: get_handle_by_name((anonymous namespace)::gpi_hdl_Object<GpiObjHdl*>*, _object*) (simulatormodule.cpp:681) COUT: ==6174== by 0x1CF7351A: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF77976: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF76492: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== Address 0xed71320 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE" COUT: ==6174== ``` A GDB backtrace looks identical, with slightly more symbol information: ``` #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007fe519095893 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78 cocotb#2 0x00007fe519042846 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 cocotb#3 0x00007fe51902b81c in __GI_abort () at abort.c:79 cocotb#4 0x00007fe5190889ae in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fe5191b144f "%s\n") at ../sysdeps/posix/libc_fatal.c:155 cocotb#5 0x00007fe5190a014c in malloc_printerr (str=str@entry=0x7fe5191af0a9 "free(): invalid pointer") at malloc.c:5660 cocotb#6 0x00007fe5190a211c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=have_lock@entry=0) at malloc.c:4435 cocotb#7 0x00007fe5190a4b13 in __GI___libc_free (mem=<optimized out>) at malloc.c:3385 cocotb#8 0x00007fe514f9ea91 in std::string::assign(std::string const&) () from /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib64/python3.10/site-packages/cocotb/libs/libgpilog.so cocotb#9 0x00007fe514fbe875 in std::string::operator= (__str=..., this=0x7fe50e0d2d58) at /opt/rh/devtoolset-10/root/usr/include/c++/10/bits/basic_string.h:3726 cocotb#10 GpiObjHdl::initialise (this=0x7fe50e0d2d30, name=..., fq_name=...) at cocotb/share/lib/gpi/GpiCbHdl.cpp:74 cocotb#11 0x00007fe514f761b3 in VhpiImpl::create_gpi_obj_from_handle (this=0x7fe50c17df00, new_hdl=<optimized out>, name=..., fq_name=...) at cocotb/share/lib/vhpi/VhpiImpl.cpp:462 cocotb#12 0x00007fe514f796cb in VhpiImpl::native_check_create (this=0x7fe50c17df00, name=..., parent=<optimized out>) at cocotb/share/lib/vhpi/VhpiImpl.cpp:575 cocotb#13 0x00007fe514fc1955 in gpi_get_handle_by_name_ (skip_impl=0x0, name=..., parent=0x7fe50c0b9ea0) at cocotb/share/lib/gpi/GpiCommon.cpp:297 cocotb#14 gpi_get_handle_by_name_ (parent=0x7fe50c0b9ea0, name=..., skip_impl=0x0) at cocotb/share/lib/gpi/GpiCommon.cpp:260 cocotb#15 0x00007fe514fc1b01 in gpi_get_handle_by_name (base=0x7fe50c0b9ea0, name=0x7fe5001192a0 "i_swapper_vhdl") at cocotb/share/lib/gpi/GpiCommon.cpp:339 cocotb#16 0x00007fe5141136c6 in get_handle_by_name (self=0x7fe5000c07f0, args=<optimized out>) at cocotb/share/lib/simulator/simulatormodule.cpp:681 cocotb#17 0x00007fe51471d51b in method_vectorcall_VARARGS (func=<method_descriptor at remote 0x7fe514193970>, args=0x7fe5000f4ee8, nargsf=<optimized out>, kwnames=0x0) at Objects/descrobject.c:311 ``` This Valgrind report indicates that `free()` is called on an object which isn't intended ot be freed, and that's `std::basic_string<char, std::char_traits<char>, std::allocator<char>>::_Rep::_S_empty_rep_storage` in this case. This symbol within libstdc++ is documented as (https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/libstdc++-v3/include/bits/basic_string.h#L3230): ``` // The following storage is init'd to 0 by the linker, resulting // (carefully) in an empty string with one reference. static size_type _S_empty_rep_storage[]; ``` What seems to happen is that when we call ``` int GpiObjHdl::initialise(const std::string &name, const std::string &fq_name) { m_name = name; ... } ``` `m_name` gets free()'d after it got the new `name` assigned. Since `m_name` was empty/unset before, free() tries to access `_S_empty_rep_storage`. Assigning an explicit default value to `m_name` works around the problem nicely. That being said, it's unclear why free() is getting invoked on that symbol at all. It's also unclear why the same code only causes issues for a single mixed signal testcase. Finding out is unlikely to be trivial: cocotb wheels link (parts of) a static libstdc++ from RHEL7, while Riviera-PRO comes with its own dynamically-linked libstdc++. It's my hope that the workaround in this commit serves us long enough before it becomes a problem in itself. Fixes cocotb#3078
imphil
added a commit
that referenced
this issue
Oct 13, 2022
cocotb crashes when running the mixed language example with Riviera-PRO, using a Verilog toplevel and the pre-built binary wheels (manylinux2014, built on CentOS7). Valgrind reports ``` COUT: ==6174== Invalid free() / delete / delete[] / realloc() COUT: ==6174== at 0xC78271B: operator delete(void*) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) COUT: ==6174== by 0x1CE1AC80: std::string::assign(std::string const&) (in /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib/python3.10/site-packages/cocotb/libs/libgpilog.so) COUT: ==6174== by 0x1CDE56C6: GpiObjHdl::initialise(std::string const&, std::string const&) (GpiCbHdl.cpp:74) COUT: ==6174== by 0x1CE3D587: VhpiObjHdl::initialise(std::string const&, std::string const&) (VhpiCbHdl.cpp:258) COUT: ==6174== by 0x1CE46932: VhpiImpl::create_gpi_obj_from_handle(unsigned int*, std::string&, std::string&) (VhpiImpl.cpp:462) COUT: ==6174== by 0x1CE470E5: VhpiImpl::native_check_create(std::string&, GpiObjHdl*) (VhpiImpl.cpp:575) COUT: ==6174== by 0x1CDE6E1E: gpi_get_handle_by_name_(GpiObjHdl*, std::string, GpiImplInterface*) (GpiCommon.cpp:297) COUT: ==6174== by 0x1CDE711C: gpi_get_handle_by_name (GpiCommon.cpp:339) COUT: ==6174== by 0x14BF9595: get_handle_by_name((anonymous namespace)::gpi_hdl_Object<GpiObjHdl*>*, _object*) (simulatormodule.cpp:681) COUT: ==6174== by 0x1CF7351A: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF77976: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF76492: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== Address 0xed71320 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE" COUT: ==6174== ``` A GDB backtrace looks identical, with slightly more symbol information: ``` #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007fe519095893 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78 #2 0x00007fe519042846 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007fe51902b81c in __GI_abort () at abort.c:79 #4 0x00007fe5190889ae in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fe5191b144f "%s\n") at ../sysdeps/posix/libc_fatal.c:155 #5 0x00007fe5190a014c in malloc_printerr (str=str@entry=0x7fe5191af0a9 "free(): invalid pointer") at malloc.c:5660 #6 0x00007fe5190a211c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=have_lock@entry=0) at malloc.c:4435 #7 0x00007fe5190a4b13 in __GI___libc_free (mem=<optimized out>) at malloc.c:3385 #8 0x00007fe514f9ea91 in std::string::assign(std::string const&) () from /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib64/python3.10/site-packages/cocotb/libs/libgpilog.so #9 0x00007fe514fbe875 in std::string::operator= (__str=..., this=0x7fe50e0d2d58) at /opt/rh/devtoolset-10/root/usr/include/c++/10/bits/basic_string.h:3726 #10 GpiObjHdl::initialise (this=0x7fe50e0d2d30, name=..., fq_name=...) at cocotb/share/lib/gpi/GpiCbHdl.cpp:74 #11 0x00007fe514f761b3 in VhpiImpl::create_gpi_obj_from_handle (this=0x7fe50c17df00, new_hdl=<optimized out>, name=..., fq_name=...) at cocotb/share/lib/vhpi/VhpiImpl.cpp:462 #12 0x00007fe514f796cb in VhpiImpl::native_check_create (this=0x7fe50c17df00, name=..., parent=<optimized out>) at cocotb/share/lib/vhpi/VhpiImpl.cpp:575 #13 0x00007fe514fc1955 in gpi_get_handle_by_name_ (skip_impl=0x0, name=..., parent=0x7fe50c0b9ea0) at cocotb/share/lib/gpi/GpiCommon.cpp:297 #14 gpi_get_handle_by_name_ (parent=0x7fe50c0b9ea0, name=..., skip_impl=0x0) at cocotb/share/lib/gpi/GpiCommon.cpp:260 #15 0x00007fe514fc1b01 in gpi_get_handle_by_name (base=0x7fe50c0b9ea0, name=0x7fe5001192a0 "i_swapper_vhdl") at cocotb/share/lib/gpi/GpiCommon.cpp:339 #16 0x00007fe5141136c6 in get_handle_by_name (self=0x7fe5000c07f0, args=<optimized out>) at cocotb/share/lib/simulator/simulatormodule.cpp:681 #17 0x00007fe51471d51b in method_vectorcall_VARARGS (func=<method_descriptor at remote 0x7fe514193970>, args=0x7fe5000f4ee8, nargsf=<optimized out>, kwnames=0x0) at Objects/descrobject.c:311 ``` This Valgrind report indicates that `free()` is called on an object which isn't intended ot be freed, and that's `std::basic_string<char, std::char_traits<char>, std::allocator<char>>::_Rep::_S_empty_rep_storage` in this case. This symbol within libstdc++ is documented as (https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/libstdc++-v3/include/bits/basic_string.h#L3230): ``` // The following storage is init'd to 0 by the linker, resulting // (carefully) in an empty string with one reference. static size_type _S_empty_rep_storage[]; ``` What seems to happen is that when we call ``` int GpiObjHdl::initialise(const std::string &name, const std::string &fq_name) { m_name = name; ... } ``` `m_name` gets free()'d after it got the new `name` assigned. Since `m_name` was empty/unset before, free() tries to access `_S_empty_rep_storage`. Assigning an explicit default value to `m_name` works around the problem nicely. That being said, it's unclear why free() is getting invoked on that symbol at all. It's also unclear why the same code only causes issues for a single mixed signal testcase. Finding out is unlikely to be trivial: cocotb wheels link (parts of) a static libstdc++ from RHEL7, while Riviera-PRO comes with its own dynamically-linked libstdc++. It's my hope that the workaround in this commit serves us long enough before it becomes a problem in itself. Fixes #3078
imphil
added a commit
to imphil/cocotb
that referenced
this issue
Nov 10, 2022
cocotb crashes when running the mixed language example with Riviera-PRO, using a Verilog toplevel and the pre-built binary wheels (manylinux2014, built on CentOS7). Valgrind reports ``` COUT: ==6174== Invalid free() / delete / delete[] / realloc() COUT: ==6174== at 0xC78271B: operator delete(void*) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) COUT: ==6174== by 0x1CE1AC80: std::string::assign(std::string const&) (in /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib/python3.10/site-packages/cocotb/libs/libgpilog.so) COUT: ==6174== by 0x1CDE56C6: GpiObjHdl::initialise(std::string const&, std::string const&) (GpiCbHdl.cpp:74) COUT: ==6174== by 0x1CE3D587: VhpiObjHdl::initialise(std::string const&, std::string const&) (VhpiCbHdl.cpp:258) COUT: ==6174== by 0x1CE46932: VhpiImpl::create_gpi_obj_from_handle(unsigned int*, std::string&, std::string&) (VhpiImpl.cpp:462) COUT: ==6174== by 0x1CE470E5: VhpiImpl::native_check_create(std::string&, GpiObjHdl*) (VhpiImpl.cpp:575) COUT: ==6174== by 0x1CDE6E1E: gpi_get_handle_by_name_(GpiObjHdl*, std::string, GpiImplInterface*) (GpiCommon.cpp:297) COUT: ==6174== by 0x1CDE711C: gpi_get_handle_by_name (GpiCommon.cpp:339) COUT: ==6174== by 0x14BF9595: get_handle_by_name((anonymous namespace)::gpi_hdl_Object<GpiObjHdl*>*, _object*) (simulatormodule.cpp:681) COUT: ==6174== by 0x1CF7351A: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF77976: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF76492: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== Address 0xed71320 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE" COUT: ==6174== ``` A GDB backtrace looks identical, with slightly more symbol information: ``` #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007fe519095893 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78 cocotb#2 0x00007fe519042846 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 cocotb#3 0x00007fe51902b81c in __GI_abort () at abort.c:79 cocotb#4 0x00007fe5190889ae in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fe5191b144f "%s\n") at ../sysdeps/posix/libc_fatal.c:155 cocotb#5 0x00007fe5190a014c in malloc_printerr (str=str@entry=0x7fe5191af0a9 "free(): invalid pointer") at malloc.c:5660 cocotb#6 0x00007fe5190a211c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=have_lock@entry=0) at malloc.c:4435 cocotb#7 0x00007fe5190a4b13 in __GI___libc_free (mem=<optimized out>) at malloc.c:3385 cocotb#8 0x00007fe514f9ea91 in std::string::assign(std::string const&) () from /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib64/python3.10/site-packages/cocotb/libs/libgpilog.so cocotb#9 0x00007fe514fbe875 in std::string::operator= (__str=..., this=0x7fe50e0d2d58) at /opt/rh/devtoolset-10/root/usr/include/c++/10/bits/basic_string.h:3726 cocotb#10 GpiObjHdl::initialise (this=0x7fe50e0d2d30, name=..., fq_name=...) at cocotb/share/lib/gpi/GpiCbHdl.cpp:74 cocotb#11 0x00007fe514f761b3 in VhpiImpl::create_gpi_obj_from_handle (this=0x7fe50c17df00, new_hdl=<optimized out>, name=..., fq_name=...) at cocotb/share/lib/vhpi/VhpiImpl.cpp:462 cocotb#12 0x00007fe514f796cb in VhpiImpl::native_check_create (this=0x7fe50c17df00, name=..., parent=<optimized out>) at cocotb/share/lib/vhpi/VhpiImpl.cpp:575 cocotb#13 0x00007fe514fc1955 in gpi_get_handle_by_name_ (skip_impl=0x0, name=..., parent=0x7fe50c0b9ea0) at cocotb/share/lib/gpi/GpiCommon.cpp:297 cocotb#14 gpi_get_handle_by_name_ (parent=0x7fe50c0b9ea0, name=..., skip_impl=0x0) at cocotb/share/lib/gpi/GpiCommon.cpp:260 cocotb#15 0x00007fe514fc1b01 in gpi_get_handle_by_name (base=0x7fe50c0b9ea0, name=0x7fe5001192a0 "i_swapper_vhdl") at cocotb/share/lib/gpi/GpiCommon.cpp:339 cocotb#16 0x00007fe5141136c6 in get_handle_by_name (self=0x7fe5000c07f0, args=<optimized out>) at cocotb/share/lib/simulator/simulatormodule.cpp:681 cocotb#17 0x00007fe51471d51b in method_vectorcall_VARARGS (func=<method_descriptor at remote 0x7fe514193970>, args=0x7fe5000f4ee8, nargsf=<optimized out>, kwnames=0x0) at Objects/descrobject.c:311 ``` This Valgrind report indicates that `free()` is called on an object which isn't intended ot be freed, and that's `std::basic_string<char, std::char_traits<char>, std::allocator<char>>::_Rep::_S_empty_rep_storage` in this case. This symbol within libstdc++ is documented as (https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/libstdc++-v3/include/bits/basic_string.h#L3230): ``` // The following storage is init'd to 0 by the linker, resulting // (carefully) in an empty string with one reference. static size_type _S_empty_rep_storage[]; ``` What seems to happen is that when we call ``` int GpiObjHdl::initialise(const std::string &name, const std::string &fq_name) { m_name = name; ... } ``` `m_name` gets free()'d after it got the new `name` assigned. Since `m_name` was empty/unset before, free() tries to access `_S_empty_rep_storage`. Assigning an explicit default value to `m_name` works around the problem nicely. That being said, it's unclear why free() is getting invoked on that symbol at all. It's also unclear why the same code only causes issues for a single mixed signal testcase. Finding out is unlikely to be trivial: cocotb wheels link (parts of) a static libstdc++ from RHEL7, while Riviera-PRO comes with its own dynamically-linked libstdc++. It's my hope that the workaround in this commit serves us long enough before it becomes a problem in itself. Fixes cocotb#3078
imphil
added a commit
that referenced
this issue
Nov 12, 2022
cocotb crashes when running the mixed language example with Riviera-PRO, using a Verilog toplevel and the pre-built binary wheels (manylinux2014, built on CentOS7). Valgrind reports ``` COUT: ==6174== Invalid free() / delete / delete[] / realloc() COUT: ==6174== at 0xC78271B: operator delete(void*) (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) COUT: ==6174== by 0x1CE1AC80: std::string::assign(std::string const&) (in /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib/python3.10/site-packages/cocotb/libs/libgpilog.so) COUT: ==6174== by 0x1CDE56C6: GpiObjHdl::initialise(std::string const&, std::string const&) (GpiCbHdl.cpp:74) COUT: ==6174== by 0x1CE3D587: VhpiObjHdl::initialise(std::string const&, std::string const&) (VhpiCbHdl.cpp:258) COUT: ==6174== by 0x1CE46932: VhpiImpl::create_gpi_obj_from_handle(unsigned int*, std::string&, std::string&) (VhpiImpl.cpp:462) COUT: ==6174== by 0x1CE470E5: VhpiImpl::native_check_create(std::string&, GpiObjHdl*) (VhpiImpl.cpp:575) COUT: ==6174== by 0x1CDE6E1E: gpi_get_handle_by_name_(GpiObjHdl*, std::string, GpiImplInterface*) (GpiCommon.cpp:297) COUT: ==6174== by 0x1CDE711C: gpi_get_handle_by_name (GpiCommon.cpp:339) COUT: ==6174== by 0x14BF9595: get_handle_by_name((anonymous namespace)::gpi_hdl_Object<GpiObjHdl*>*, _object*) (simulatormodule.cpp:681) COUT: ==6174== by 0x1CF7351A: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF77976: _PyEval_EvalFrameDefault (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== by 0x1CF76492: ??? (in /usr/lib64/libpython3.10.so.1.0) COUT: ==6174== Address 0xed71320 is 0 bytes inside data symbol "_ZNSs4_Rep20_S_empty_rep_storageE" COUT: ==6174== ``` A GDB backtrace looks identical, with slightly more symbol information: ``` #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007fe519095893 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78 #2 0x00007fe519042846 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007fe51902b81c in __GI_abort () at abort.c:79 #4 0x00007fe5190889ae in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fe5191b144f "%s\n") at ../sysdeps/posix/libc_fatal.c:155 #5 0x00007fe5190a014c in malloc_printerr (str=str@entry=0x7fe5191af0a9 "free(): invalid pointer") at malloc.c:5660 #6 0x00007fe5190a211c in _int_free (av=<optimized out>, p=<optimized out>, have_lock=have_lock@entry=0) at malloc.c:4435 #7 0x00007fe5190a4b13 in __GI___libc_free (mem=<optimized out>) at malloc.c:3385 #8 0x00007fe514f9ea91 in std::string::assign(std::string const&) () from /home/philipp/src/cocotb-riviera-debug-3078-binary/.direnv/python-3.10.7/lib64/python3.10/site-packages/cocotb/libs/libgpilog.so #9 0x00007fe514fbe875 in std::string::operator= (__str=..., this=0x7fe50e0d2d58) at /opt/rh/devtoolset-10/root/usr/include/c++/10/bits/basic_string.h:3726 #10 GpiObjHdl::initialise (this=0x7fe50e0d2d30, name=..., fq_name=...) at cocotb/share/lib/gpi/GpiCbHdl.cpp:74 #11 0x00007fe514f761b3 in VhpiImpl::create_gpi_obj_from_handle (this=0x7fe50c17df00, new_hdl=<optimized out>, name=..., fq_name=...) at cocotb/share/lib/vhpi/VhpiImpl.cpp:462 #12 0x00007fe514f796cb in VhpiImpl::native_check_create (this=0x7fe50c17df00, name=..., parent=<optimized out>) at cocotb/share/lib/vhpi/VhpiImpl.cpp:575 #13 0x00007fe514fc1955 in gpi_get_handle_by_name_ (skip_impl=0x0, name=..., parent=0x7fe50c0b9ea0) at cocotb/share/lib/gpi/GpiCommon.cpp:297 #14 gpi_get_handle_by_name_ (parent=0x7fe50c0b9ea0, name=..., skip_impl=0x0) at cocotb/share/lib/gpi/GpiCommon.cpp:260 #15 0x00007fe514fc1b01 in gpi_get_handle_by_name (base=0x7fe50c0b9ea0, name=0x7fe5001192a0 "i_swapper_vhdl") at cocotb/share/lib/gpi/GpiCommon.cpp:339 #16 0x00007fe5141136c6 in get_handle_by_name (self=0x7fe5000c07f0, args=<optimized out>) at cocotb/share/lib/simulator/simulatormodule.cpp:681 #17 0x00007fe51471d51b in method_vectorcall_VARARGS (func=<method_descriptor at remote 0x7fe514193970>, args=0x7fe5000f4ee8, nargsf=<optimized out>, kwnames=0x0) at Objects/descrobject.c:311 ``` This Valgrind report indicates that `free()` is called on an object which isn't intended ot be freed, and that's `std::basic_string<char, std::char_traits<char>, std::allocator<char>>::_Rep::_S_empty_rep_storage` in this case. This symbol within libstdc++ is documented as (https://github.com/gcc-mirror/gcc/blob/releases/gcc-10/libstdc++-v3/include/bits/basic_string.h#L3230): ``` // The following storage is init'd to 0 by the linker, resulting // (carefully) in an empty string with one reference. static size_type _S_empty_rep_storage[]; ``` What seems to happen is that when we call ``` int GpiObjHdl::initialise(const std::string &name, const std::string &fq_name) { m_name = name; ... } ``` `m_name` gets free()'d after it got the new `name` assigned. Since `m_name` was empty/unset before, free() tries to access `_S_empty_rep_storage`. Assigning an explicit default value to `m_name` works around the problem nicely. That being said, it's unclear why free() is getting invoked on that symbol at all. It's also unclear why the same code only causes issues for a single mixed signal testcase. Finding out is unlikely to be trivial: cocotb wheels link (parts of) a static libstdc++ from RHEL7, while Riviera-PRO comes with its own dynamically-linked libstdc++. It's my hope that the workaround in this commit serves us long enough before it becomes a problem in itself. Fixes #3078
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
We want to know where all the time is going.
Initially, knowing how much time is spent in the simulator vs. how much time is spent in callback handlers would be a very useful indicator. This should be easy to do since all callbacks go through the same handler.
The text was updated successfully, but these errors were encountered: