在这里和这里之前已经提出了与这个问题中的一个相似的点,并且我知道Google coredump库(我已经评估并发现它缺乏,但是如果我更好地理解这个问题,我可能会尝试并努力).
我想在不中断进程的情况下获取正在运行的Linux进程的核心转储.自然的方法是说:
if (!fork()) { abort(); }
Run Code Online (Sandbox Code Playgroud)
由于分叉进程获得原始进程内存的固定快照副本,因此我应该获得完整的核心转储,并且由于副本使用写时复制,因此通常应该很便宜.但是,这种方法的一个关键缺点是fork()
只分叉当前线程,并且原始进程的所有其他线程将不存在于分叉副本中.
我的问题是,是否有可能以某种方式获得其他原始线程的相关数据.我不完全确定如何解决这个问题,但这里有几个我提出的子问题:
包含所有线程堆栈的内存是否仍然可用并在分叉进程中可访问?
是否可以(快速)枚举原始进程中的所有正在运行的线程并存储其堆栈基址的地址?据我了解,Linux上的线程堆栈的基础包含指向内核的线程簿记数据的指针,所以......
使用存储的线程基地址,您能读出分叉进程中每个原始线程的相关数据吗?
如果可能,也许只需要将其他线程的数据附加到核心转储.但是,如果该数据已经在fork的位置丢失,那么这种方法似乎没有任何希望.
我正在研究Linux的堆分析器,称为heaptrack.目前,我依赖于LD_PRELOAD
重载各种(解)分配函数,这非常有效.
现在我想扩展该工具以允许运行时附加到现有进程,该进程是在没有LD_PRELOAD
我的工具的情况下启动的.我可以dlopen
通过GDB很好地使用我的库,但是这不会覆盖malloc
等等.我认为,这是因为此时链接器已经解决了已经运行的进程的位置相关代码 - 正确吗?
那么我该怎么办才能超载malloc
和朋友呢?
我不熟悉汇编代码.从我到目前为止所读到的,我想我将以某种方式必须修补malloc
和其他功能,以便他们首先回调我的跟踪功能,然后继续他们的实际实现?那是对的吗?我怎么做?
我希望有现有的工具,或者我可以利用GDB/ptrace.
如何遍历当前进程的所有线程的所有tid?有什么方法不涉及潜入/proc
?
假设我们有一个单线程程序,并且希望在发生预定义的中断(例如定时器中断)时捕获程序计数器(PC)的值。
如您所知,这似乎很容易,我们只需要使用一个特殊的关键字编写一个特定的汇编代码__asm__
,然后在将移位4字节后将值弹出堆栈顶部即可。
那多线程程序呢?
我们如何从同一进程中运行的另一个线程获取所有线程的值?(从运行在多核处理器中单独内核上的线程获取值似乎非常不可思议)。(在多线程程序中,每个线程都有其堆栈并进行注册)。
我想实现破坏分子。
为了在目标多线程程序中执行故障注入,故障模型为SEU(单错误翻转),这意味着程序计数器寄存器中的任意位被随机修改(位翻转),从而导致违反正确的程序顺序。因此,会发生控制流错误(CFE)。
由于我们的目标程序是一个多线程程序,因此我们必须在所有线程的PC上执行故障注入。这是破坏分子的任务。它应该能够获得线程的PC来执行故障注入。假设我们有这段代码,
main ()
{
foo
}
void foo()
{
__asm__{
pop "%eax"
pop "%ebx" // now ebx holds porgram counter value (for main thread)
// her code injection like 00000111 XOR ebx for example
push ...
push ...
};
}
Run Code Online (Sandbox Code Playgroud)
如果我们的程序是多线程程序。这是否意味着我们有多个堆栈?
当OS执行上下文切换时,这意味着正在运行的线程的堆栈和寄存器已移动到内存中的某个位置。这是否意味着如果我们要获取这些线程的程序计数器的值,就可以在内存中找到它们?哪里?并且在运行时有可能吗?