停止进程但堆仍在变化

Stopped Process but heap is still changing

我已经通过使用 ptrace() 系统调用跟踪它停止了一个进程。这实际上向进程发送了 kill -sigstop <pid>

现在我检查从 /proc/<pid>/maps

获得的 [heap] 区域

但是在堆内存范围内读出某些地址returns不同的值!

ptrace(PEEKDATA*, <pid>, <addr>, null) => 33  
ptrace(PEEKDATA*, <pid>, <addr>, null) => 34
ptrace(PEEKDATA*, <pid>, <addr>, null) => 34 

随着时间的推移(不重复调用)值增加 1,直到字节在 63 处溢出并再次从 0 开始!

我做了健全性测试并直接从 /proc/<pid>/mem 中读出了值 其中 returns 相同的值。随着时间的推移,它也在增加。

更多背景: 我正在 ptrace() 玩一款名为 Rogue Legacy 的游戏,其堆大小约为 2 亿个地址。游戏的进程层次结构如下所示:

更新: ptrace 附加到各个线程。它以 pid 作为参数,但 pid 既可以是进程也可以是线程。我假设它始终是一个过程,只是现在这个不准确的模型对我来说是错误的。那么,在我的示例中,"RogueLegacy.bin" 只是一个跟踪线程,还有另一个未停止的线程导致堆更改。

多个线程共享堆作为公共资源。这也意味着 我们必须小心处理多线程应用程序中的 peekdata,因为受到审查的数据可能会因其他 运行 线程的主权而发生变化。

我想我已经缩小到一个解决方案:

给定一个多线程应用程序,所有线程都共享相同的堆地址-space

  • foo-thread
  • 条形线
  • qux线程

    进程 运行 我们的 ptrace 调用(在本例中为单线程进程):

  • 跟踪线程

    如果我们 ptrace(PTRACE_ATTACH ..) 到 foo-thread,我们使 tracer-thread 的另一个父线程 foo-thread。根据 ptrace 的文档,发送一个 SIGSTOP,停止 线程。但是这个由 tracer-thread 发送的 SIGSTOP 只停止 foo-thread 而不是任何 其他线程!

    但是如果我们直接向 foo-thread 发送 SIGSTOP即不是通过 attach ptrace call,那么整个进程,它的线程foo-和bar-thread是 停止了。

    这是 ptrace 成为临时寄养家庭的特殊性的一个例子 必须考虑线程。