【问题标题】:How can I get a running thread's start address on linux?如何在 linux 上获取正在运行的线程起始地址?
【发布时间】:2014-03-14 20:24:27
【问题描述】:

问题陈述

我正在尝试获取在 pthread_create() 调用中传递的正在运行的线程的 start_routine 的地址。

研究至今

它显然不在 /proc/[tid]/stat 或 /proc/[tid]/status 中。

我发现 start_routine 是 struct pthread 的成员,并由 pthread_create 设置。[1] 如果我知道这个结构的地址,我就可以读取 start_routine 地址。

我还发现调试库thread_db.h中定义了td_thr_get_info。[2] 它用有关线程的信息填充结构,包括启动函数。 [3]但它需要一个 struct td_thragent 作为参数,我不知道如何正确创建它。

链接

[1]http://fxr.watson.org/fxr/source/nptl/pthread_create.c?v=GLIBC27;im=excerpts#L455

[2]http://fxr.watson.org/fxr/source/nptl_db/td_thr_get_info.c?v=GLIBC27#L27

[3] 见评论,因为我不能发布超过 2 个链接。

【问题讨论】:

标签: linux multithreading memory-address


【解决方案1】:

你可能不能,我什至可以想象一个非常疯狂的场景,在你查询它的那一刻它不可能存在。

假设初始线程启动例程void*foo_start(void*) 在某个dlopen-ed 动态共享库libfoo.so 中。

让我们假设foo_start 正在将tail-recursive call 转换为bar,而bar 函数是dlclose-ing libfoo.so,然后调用您的一些例程查询开始。它是某个失效段中的一个野地址(由dlclosebar 调用的munmap 编辑)!

因此,即使您破解 libc 以检索线程的启动例程,这也没有多大意义。顺便说一句,你可以查看MUSL libc,它的src/thread/pthread_create.c 文件可读性很强。

注意:在某些情况下,最近的 GCC(例如 4.8 或 4.9)当被要求优化很多时(例如 -O3)能够从 C 代码生成尾递归调用。

【讨论】:

  • 我不想使用这个功能,我只想知道它的地址。函数的 dll 是否被卸载并不重要。
  • 为什么要知道启动函数的地址?干什么用的?
猜你喜欢
  • 2019-07-17
  • 1970-01-01
  • 2018-12-18
  • 1970-01-01
  • 2011-01-04
  • 2012-07-18
  • 1970-01-01
  • 2012-06-24
  • 1970-01-01
相关资源
最近更新 更多