libunwind-ptrace -- ptrace() support in libunwind

Posted rtoax

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了libunwind-ptrace -- ptrace() support in libunwind相关的知识,希望对你有一定的参考价值。

libunwind-ptrace(3)https://www.nongnu.org/libunwind/man/libunwind-ptrace(3).html

libunwind-ptrace -- ptrace() support in libunwind

Synopsis

#include <libunwind-ptrace.h>

unw_accessors_t _UPT_accessors;

void *_UPT_create(pid_t);
void _UPT_destroy(void *);

int _UPT_find_proc_info(unw_addr_space_t, unw_word_t, unw_proc_info_t *, int, void *);
void _UPT_put_unwind_info(unw_addr_space_t, unw_proc_info_t *, void *);
int _UPT_get_dyn_info_list_addr(unw_addr_space_t, unw_word_t *, void *);
int _UPT_access_mem(unw_addr_space_t, unw_word_t, unw_word_t *, int, void *);
int _UPT_access_reg(unw_addr_space_t, unw_regnum_t, unw_word_t *, int, void *);
int _UPT_access_fpreg(unw_addr_space_t, unw_regnum_t, unw_fpreg_t *, int, void *);
int _UPT_get_proc_name(unw_addr_space_t, unw_word_t, char *, size_t, unw_word_t *, void *);
int _UPT_resume(unw_addr_space_t, unw_cursor_t *, void *);

Description

The ptrace(2) system-call makes it possible for a process to gain access to the machine-state and virtual memory of another process. With the right set of call-back routines, it is therefore possible to hook up libunwind to another process via ptrace(2). While it's not very difficult to do so directly, libunwind further facilitates this task by providing ready-to-use callbacks for this purpose. The routines and variables implementing this facility use a name-prefix of _UPT, which is stands for ``unwind-via-ptrace''.

ptrace(2) 系统调用使一个进程可以访问另一个进程的机器状态和虚拟内存。 使用正确的回调例程集,因此可以通过 ptrace(2) 将 libunwind 连接到另一个进程。 虽然直接执行此操作并不难,但 libunwind 通过为此目的提供随时可用的回调进一步简化了此任务。 实现此功能的例程和变量使用 _UPT 的名称前缀,它代表“unwind-via-ptrace”。

An application that wants to use the _UPT-facility first needs to create a new libunwind address-space that represents the target process. This is done by calling unw_create_addr_space(). In many cases, the application will simply want to pass the address of _UPT_accessors as the first argument to this routine. Doing so will ensure that libunwind will be able to properly unwind the target process. However, in special circumstances, an application may prefer to use only portions of the _UPT-facility. For this reason, the individual callback routines (_UPT_find_proc_info(), _UPT_put_unwind_info(), etc.) are also available for direct use. Of course, the addresses of these routines could also be picked up from _UPT_accessors, but doing so would prevent static initialization. Also, when using _UPT_accessors, all the callback routines will be linked into the application, even if they are never actually called.

想要使用 _UPT 设施的应用程序首先需要创建一个新的 libunwind 地址空间来表示目标进程。 这是通过调用 unw_create_addr_space() 来完成的。 在许多情况下,应用程序只想将 _UPT_accessors 的地址作为第一个参数传递给该例程。 这样做将确保 libunwind 能够正确展开目标进程。 但是,在特殊情况下,应用程序可能更喜欢仅使用 _UPT 设施的一部分。 因此,单个回调例程(_UPT_find_proc_info()、_UPT_put_unwind_info() 等)也可直接使用。 当然,这些例程的地址也可以从 _UPT_accessors 中获取,但这样做会阻止静态初始化。 此外,当使用 _UPT_accessors 时,所有回调例程都将链接到应用程序中,即使它们从未被实际调用过。

Next, the application can turn on ptrace-mode on the target process, either by forking a new process, invoking PTRACE_TRACEME, and then starting the target program (via execve(2)), or by directly attaching to an already running process (via PTRACE_ATTACH). Either way, once the process-ID (pid) of the target process is known, a _UPT-info-structure can be created by calling _UPT_create(), passing the pid of the target process as the only argument. The returned void-pointer then needs to be passed as the ``argument'' pointer (third argument) to unw_init_remote().

接下来,应用程序可以在目标进程上打开 ptrace 模式,方法是创建一个新进程,调用 PTRACE_TRACEME,然后启动目标程序(通过 execve(2)),或者直接附加到一个已经运行的进程(通过 PTRACE_ATTACH)。 无论哪种方式,一旦知道目标进程的进程 ID (pid),就可以通过调用 _UPT_create() 来创建 _UPT-info-structure,将目标进程的 pid 作为唯一参数传递。 然后需要将返回的空指针作为“参数”指针(第三个参数)传递给 unw_init_remote()。

The _UPT_resume() routine can be used to resume execution of the target process. It simply invokes ptrace(2) with a command value of PTRACE_CONT.

_UPT_resume() 例程可用于恢复目标进程的执行。 它只是使用 PTRACE_CONT 的命令值调用 ptrace(2)。

When the application is done using libunwind on the target process, _UPT_destroy() needs to be called, passing it the void-pointer that was returned by the corresponding call to _UPT_create(). This ensures that all memory and other resources are freed up.

当应用程序在目标进程上使用 libunwind 完成时,需要调用 _UPT_destroy(),将相应调用返回的空指针传递给 _UPT_create()。 这可确保释放所有内存和其他资源。

Availability

Since ptrace(2) works within a single machine only, the _UPT-facility by definition is not available in libunwind-versions configured for cross-unwinding.

Thread Safety

The _UPT-facility assumes that a single _UPT-info structure is never shared between threads. Because of this, no explicit locking is used. As long as only one thread uses a _UPT-info structure at any given time, this facility is thread-safe.

Return Value

_UPT_create() may return a NULL pointer if it fails to create the _UPT-info-structure for any reason. For the current implementation, the only reason this call may fail is when the system is out of memory.

Files

libunwind-ptrace.h

Headerfile to include when using the interface defined by this library.

-lunwind-ptrace -lunwind-generic

Linker-switches to add when building a program that uses the functions defined by this library.

See Also

execve(2), libunwind(3), ptrace(2)

Author

David Mosberger-Tang
Email: dmosberger@gmail.com
WWW: The libunwind project.

以上是关于libunwind-ptrace -- ptrace() support in libunwind的主要内容,如果未能解决你的问题,请参考以下文章