enable tracking of C memory allocations#57
Conversation
|
Nice stuff. Rather than putting this into zoslib, can you explore putting it into the clang address analyzer (https://clang.llvm.org/docs/AddressSanitizer.html). More people know about this. |
Thanks. Wouldn't that require adding support for those features (AddressSanitizer, LeakSanitizer, ?) to z/OS clang, using the same implementation as done for the other supported platforms? Here we also track allocations from iarv64 and 31-bit, and support an app to call |
| // returns timestamp as yyyy-mm-dd hh:mm:ss, so char ts[20] | ||
| time_t lt = time(NULL); | ||
| struct tm *tm = localtime(<); | ||
| sprintf(ts,"%04d-%02d-%02d %02d:%02d:%02d", tm->tm_year+1900, |
There was a problem hiding this comment.
Should you check the return code in sprintf and return NULL if -1?
IgorTodorovskiIBM
left a comment
There was a problem hiding this comment.
One comment, otherwise LGTM. Thanks!
Also init the passed ts arg to "(error)" in case an error occurred, instead of checking the return code.
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.