-
do you have a paper or more docs to descripe it ? thx very much |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
I should write some docs on this, but we don't have any today. I'll try to explain some stuff here, with a goal of eventually writing some docs that explain this all. There's basically 4 different major pieces to how Memray captures information about allocations:
Detecting when memory is allocatedAny C or C++ extension module dynamically links against Whenever you dynamically link against some library, you know what symbols you need from it, but not what address in the program's address space those symbols will be found at when the program runs - because libraries can be loaded anywhere in your program's address space. So, when you link against a shared library, the linker creates a mapping table (called the "procedure linkage table") of function pointers for each of the undefined symbols that the built library depends upon from other libraries. Those default to null pointers, but the runtime loader -
and when it's loaded, the runtime loader overwrites that table to something sort of like:
The whole story is more complicated than that, but that simplification is enough to understand how Memray works: when you tell Memray to start tracking allocations, it searches for all of those tables in every library loaded by the process, and replaces all of the malloc/free/realloc etc entries with its own functions that a) record information about the allocation to a capture file, and then b) call the original malloc/free/realloc function that was originally in the table. When you tell Memray to stop tracking allocations, it restores the original function pointers back into those tables. Naturally the exact details are different on macOS and on Linux, and there are some tricks to how those tables are located and modified, and we need to do extra work to detect when new libraries are loaded so that we can patch their tables as well, but the basic answer to how Memray detects allocations is that it patches Procedure Linkage Tables to interpose its own code around calls to the allocators provided by libc. Recording the Python stackAgain, there are some complex tricks that we need to play here, but the basic idea is pretty easy: we use a Python profile function with Recording the native stackWe actually do have some documentation on this: https://bloomberg.github.io/memray/native_mode.html covers it. Whenever a library is loaded, we record to the capture file what file path was loaded, and where in memory it was loaded. Later, at the point when an allocation occurs, we use Detecting Python allocator allocationshttps://bloomberg.github.io/memray/python_allocators.html describes what the Python allocators are. There's a supported API provided by CPython for swapping in your own allocators that wrap the default ones - when you use |
Beta Was this translation helpful? Give feedback.
I should write some docs on this, but we don't have any today. I'll try to explain some stuff here, with a goal of eventually writing some docs that explain this all.
There's basically 4 different major pieces to how Memray captures information about allocations:
malloc
,free
,realloc
, etc)--native
is used)--trace-python-allocators
is used)Detecting when memory is allocated
Any C or C++ extens…