enable tracking of C memory allocations #57
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This change was previously done in the internal zoslib to investigate a memory leak in a customer app running Node.js.
Previously, tracking of memory [de]allocations was only performed on memory from virtual storage (iarv64) and __malloc31, by using a
std::unordered_mapto store each allocated pointer and its size, and that was always performed regardless of any compiler option.In this PR each allocation from malloc, calloc, realloc, strdup, strndup, iarv64 and __malloc31 is stored as a node (
__taddr_t) in a binary search tree that stores, for each allocation, the allocated address (key), its size, source (filename:linenum) from which the allocation call was made, and the address space (31-bit, 64-bit heap or 64-bit virtual storage). This is enabled only when zoslib and the app are built withCFLAGS=CXXFLAGS=-DZOSLIB_TRACE_ALLOCSAnother binary search tree keeps track of all source locations (filename:linenum) that allocated memory, storing details such as the filename:linenum (key), num of bytes currently still allocated from this location, max num of bytes allocated from this location, num of times an allocation has been called from this location, num of times an allocation from this location has been freed, and the address space for the allocation from this source.
It's possible to display the allocations report (e.g. below) by calling
__display_alloc_stats(false, false);whenever some signal is received (e.g. SIGUSR2), where the 2nd arg is false so the report only contains those allocations that changed since the last report. This would be useful to monitor the memory status for a long-running app.As a test, I ran zoslib's
cctest_a; the report shows all C allocations it makes, as well as a few memory leaks:The new internal environment variable
__MEMORY_USAGE_ALLOC_TB_WARNINGis effective only if__MEMORY_USAGE_LOG_LEVELis 1 or 2, and results in a traceback whenever a warning is encountered (e.g. address being freed is not in cache, or address allocated is already in cache, or realloc called with ptr=0 and new-size=0).and the following with example settings:
result in a source traceback displayed whenever an allocation is made from the given
__MEMORY_USAGE_ALLOC_TB_SOURCE,or if
__MEMORY_USAGE_ALLOC_TB_SOURCE_Iis set, then when only the i'th allocation from the given source is made,or if
__MEMORY_USAGE_ALLOC_TB_SOURCE_Jis also set, then when only the allocation occurrence from the givenlocation is between the given range. A range will almost always be required because the order of allocations usually differs between different runs for the same test.