Attaching to a running process¶
Memray allows you to attach to a running process and to observe the allocations it performs once you’ve attached. This doesn’t allow you to see where memory was allocated before you attached to the process, but it does allow you to observe or record future allocations. This can be useful if an application is continuing to request more memory than you think it should need, and you want to figure out why. It can also be useful for observing the allocation patterns of a long running process once the process has already completed any initial warm up steps that it needs to do.
Basic Usage¶
The general form of the attach
subcommand is:
memray attach [options] <pid>
The only required argument for memray attach
is a process ID to attempt to
attach to. You must be able to attach a debugger to that
process, and that process must be a Python process, and the Memray package
must be installed in the environment that the process is running in. That
is, memray attach
will execute the Python statement import memray
in
the process being attached to, and that import must succeed for attaching to
work.
By default this will open a live mode TUI showing the allocations
that the process performs after you’ve attached, but you can instead provide
the name of a capture file to write to with the -o
option, allowing you to
analyze the captured allocations with any Memray reporter you’d like. You can
also provide most of the options that memray run
accepts. See the
CLI reference for details.
If you use the -o
option, the process will continue recording allocations
to the capture file even after memray attach
has returned. Otherwise,
allocations are tracked only for as long as the live mode TUI
continues running. Once you quit the TUI, the attached process will stop
tracking allocations. If you later reattach to the same process, it will start
from a clean slate, and will not be aware of any allocations seen during your
first TUI session.
Debugger Privileges¶
Memray leverages a debugger for attaching to the process. It is compatible with
both gdb and lldb, but one or the other must be installed in order for memray
attach
to work. Only a super user (either root, or a user with the
CAP_SYS_PTRACE
capability) can attach to processes run by another user.
Further, security settings on modern Linux systems typically prevent a regular
user from attaching even to their own processes. You can loosen that
restriction by writing 0
to /proc/sys/kernel/yama/ptrace_scope
as root,
allowing any user to attach to their own processes. When running a Docker
container, you can use --cap-add=SYS_PTRACE
to allow attaching to processes
within the container.
Warning
Allowing arbitrary processes to be traced is insecure, as it provides an easy vector for privilege escalation within a remote code execution attack. Be sure to consider the security implications before you choose to grant regular users the ability to attach to processes.
In some cases (like MacOS), the debugger may require you to authenticate with your username and password in order to attach to a process. In that case it is possible that a window will pop up asking for your password or for biometric authentication.
Caveats¶
memray attach
works by injecting executable code into a running process.
We’ve tried to do this in the safest way possible, but we can’t guarantee that
there aren’t edge cases where this might crash or deadlock the process that
you’re attempting to attach to, depending on what it’s doing at the point when
we attach. We advise only using this as a debugging tool on development
machines.
If you attach to a Python 3.7 or Python 3.8 process that has never imported the
threading
module, the attached process will show an error when the
interpreter finishes running the main script. This is due to a known bug that was not fixed until
Python 3.9. From Python 3.9 onwards there will be no error on exit, but the
interpreter will assign the wrong name to the main thread if threading
is
later imported by the script. That should not have any major effect on the
behavior of the program.
If you do find some case where memray attach
either doesn’t work or causes
a crash or deadlock, we want to hear about it! Please file a bug report
explaining what went wrong. If the issue is reproducible, please try running
memray attach
with the --verbose
flag, which outputs a lot of extra
debugging information, including the output of the debugger session that was
used to inject our code into the remote process. If the process crashed and
left a core file, please include a stack trace of all of the threads in the
process, so that we can understand what state it was in when we tried to
attach. You can show all threads’ stacks using thread apply all bt
in gdb
or thread backtrace all
in lldb.
CLI Reference¶
memray attach¶
Begin tracking allocations in an already-started process
usage: memray attach [-h] [-o FILE] [-f] [--aggregate] [--native] [--follow-fork]
[--trace-python-allocators] [--compress-on-exit | --no-compress]
[--duration DURATION] [--method {auto,gdb,lldb}] [-v]
pid
Positional Arguments¶
- pid
Process id to affect
Named Arguments¶
- -o, --output
Capture allocations into the given file instead of starting a live tracking session
- -f, --force
If the output file already exists, overwrite it
- --aggregate
Write aggregated stats to the output file instead of all allocations
- --native
Track native (C/C++) stack frames as well
- --follow-fork
Record allocations in child processes forked from the tracked script
- --trace-python-allocators
Record allocations made by the pymalloc allocator
- --compress-on-exit
Compress the resulting file using lz4 after tracking completes
- --no-compress
Do not compress the resulting file using lz4
- --duration
Duration to track for (in seconds)
- --method
Possible choices: auto, gdb, lldb
Method to use for injecting commands into the remote process
Default:
'auto'
- -v, --verbose
Print verbose debugging information.
memray detach¶
End the tracking started by a previous memray attach
call
usage: memray detach [-h] [--method {auto,gdb,lldb}] [-v] pid
Positional Arguments¶
- pid
Process id to affect
Named Arguments¶
- --method
Possible choices: auto, gdb, lldb
Method to use for injecting commands into the remote process
Default:
'auto'
- -v, --verbose
Print verbose debugging information.
Please submit feedback, ideas, and bug reports by filing a new issue at https://github.com/bloomberg/memray/issues