我通过使用ptrace()
系统调用跟踪进程来停止进程。这实际上会向流程发送kill -sigstop <pid>
。
现在我检查[heap]区域,这是我从/proc/<pid>/maps
但是读出堆内存范围中的某些地址会返回不同的值!
ptrace(PEEKDATA*, <pid>, <addr>, null) => 33
ptrace(PEEKDATA*, <pid>, <addr>, null) => 34
ptrace(PEEKDATA*, <pid>, <addr>, null) => 34
值随时间增加一(不重复调用),直到字节溢出为63并再次从0开始!
我做了一个完整性测试并直接从/proc/<pid>/mem
读出了值
返回相同的值。它也随着时间的推移而增加。
更多背景:
我是ptrace()
一个名为Rogue Legacy的游戏,其大小约为2亿个地址。游戏的过程是这样的:
更新: ptrace附加到各个线程。它需要一个pid作为参数,但pid可以是一个进程或线程。我假设它始终是一个过程,只是现在这个不准确的模型为我打破了。在我的例子中,&#34; RogueLegacy.bin&#34;只是一个跟踪线程,还有另一个线程,它没有停止,是谁导致堆更改。
多个线程将堆共享为公共资源。这也意味着 我们必须在多线程应用程序中小心peekdata,因为受到审查的数据可能会因其他正在运行的线程的主权而发生变化。
答案 0 :(得分:0)
我认为我将其缩小为一个解决方案:
给定一个带线程的多线程应用程序,它们共享相同的堆地址空间
qux线程
运行我们的ptrace调用的进程(在这种情况下是一个单线程进程):
示踪剂线程
如果我们ptrace(PTRACE_ATTACH ..)到 foo-thread ,我们将 tracer-thread 设为另一个父级 的 FOO线程即可。按照ptrace&#39;文档,SIGSTOP发送,停止 线程。但是这个由跟踪器线程发送的SIGSTOP只能阻止foo-thread 其他线程!
但是如果我们直接将 SIGSTOP发送到foo-thread ,即。不是通过的方式 附加ptrace调用,然后是整个过程,其线程为foo-和bar-thread 停止。
这是ptrace成为临时寄养家庭的特殊情况 必须考虑线程。