Fix memory leak in tracetools::get_symbol()#43
Conversation
|
I'm marking this as a draft because I would like to get feedback before updating downstream packages. This PR requires the following change in + char * symbol = tracetools::get_symbol(callback_);
TRACEPOINT(
rclcpp_callback_register,
static_cast<const void *>(&callback_),
- tracetools::get_symbol(callback_));
+ symbol);
+ std::free(symbol);Of course, we can surround this with To solve this, we can replace LTTng's if (tracepoint_enabled(name)) {
// Compute arguments here
auto args = ...;
// Then trigger tracepoint manually
do_tracepoint(name, args);
}See lttng-ust(3). Then we can first check if the tracepoint is enabled before calling |
|
Good catch! The current approach basically passes on the obligation to free the memory to the caller of get_symbol. This is the most straightforward approach, but I'm wondering whether we can come up with something to avoid it. You have thought about the pre-allocated buffer (but we would also have to free that somehow). btw, one of the other thoughts I had is whether we could output metadata throughout execution at regular intervals. This would then require us to store the metadata anyhow. I'm not saying we need that, but it's maybe something to consider in conjunction. |
This wouldn't really work if you called |
Yeah, we should keep these things separate for now. I opened an issue for this an mentioned that as a potential solution: #44. |
72fd8b9 to
17c4bde
Compare
Note that this improvement in |
17c4bde to
de1e1c7
Compare
Signed-off-by: Christophe Bedard <christophe.bedard@apex.ai>
de1e1c7 to
51b2d85
Compare
|
Testing Includes: |
|
@mjcarroll friendly ping |
|
I think this caused a fair number of regressions. This repository's CI shows breakage, and my builds on RHEL 8 are now failing as well. Stuff like: @Crola1702 FYI |
Are there any non-RHEL failures? Note that this broke ABI, so some Rpr failures are expected. But not the one you included above; that one does make sense to me, especially given that we didn't test this change on RHEL. Also, don't mind the local GitHub actions. They're broken. |
|
Looking at CI, it seems to be RHEL-only (at least regarding this PR). #48 fixes that. |
Fixes #34
tracetools::get_symbol()is used to get a demangled symbol from a function pointer orstd::functionobject. This is used to associate a human-readable string to a callback in the trace data. To do symbol demangling, it callsabi::__cxa_demangle(), which returns a pointer that must be freed by the caller. This was never freed. The best solution would be to use a limited size buffer on the stack and never allocate. However, whileabi::__cxa_demanglecan accept a pre-allocated buffer, it cannot be on the stack, sinceabi::__cxa_demangleexpands it usingreallocif it is not long enough.Since the pointer to the demangled symbol must be freed, the problem is that
tracetools::get_symbol()was returning a pointer to a literal when something failed (e.g., demangling, or mapping from function pointer to shared object), so we couldn't alwaysfree()the return value. There's no real use to returning anything other thannullptrwhen something fails.Changes:
tracetools::get_symbol()to returnchar *instead ofconst char *, and to returnnullptrwhen something failsget_symbol_funcptr(void * funcptr)toget_symbol_funcptr(const void * funcptr), since that's more appropriate#ifdef TRACETOOLS_LTTNG_ENABLEDconditions intracetools::detail::{demangle_symbol,get_symbol_funcptr}, since there's no real need to do anything different ifTRACETOOLS_LTTNG_ENABLEDis defined. These functions shouldn't be called in that case anyway.test_tracetools'stest_utils)This PR breaks ABI and requires the following downstream changes:
tracetools::get_symbol()to free the memoryTRACEPOINT_ENABLED()andDO_TRACEPOINT()macros (Add TRACEPOINT_ENABLED() and DO_TRACEPOINT() macros #46) to avoid allocating memory when the tracepoint is disabledDownstream PR:
Signed-off-by: Christophe Bedard christophe.bedard@apex.ai