对函数调用和 show_self 的限制如下:
- 它们无法调用 exec()。
- 它们无法终止线程或进程。
- 它们无法产生信号。
- 它们无法调用 longjmp(),除非 longjmp() 的目标在函数内。
- 它们无法产生 C++ 异常,除非该异常是在函数中处理的。
- 它们必须在合理时间内终止。这可以通过 DER_DBG_SHOWSELF_TIMEOUT 环境变量来控制。缺省值为 10 秒。
- 在多线程应用程序中,函数无法对它在哪个线程上运行进行假设,并且它必须假定进程中的所有其他线程都已暂挂。特别地:
- 它不能依赖于其他线程,必须假定其他线程可拥有必需资源。具体地说,调用
pthread_mutex_lock() 可导致函数挂起。
- 并非所有 C/C++ 库函数都可重入。libc.a 中许多线程安全函数(包括内存分配和输入/输出函数)不可重入。它们连续可再用。这些函数使用
pthread_mutex_lock() 来实现连续可再用性,因此调用它们不太可能会挂起调试会话。
- 对于要调试的进程,在函数返回之后,函数对该进程的全局状态进行的所有更改都将继续。
- 调用 pthread_create() 的效果未定义。
- show_self 函数包括将输出定向至控制台的调用。这些调用包括
printf()、fprintf() 和 cout 类。当对这些函数求值时,调试器会在调试对象的任意一个线程上运行
show_self 函数,而所有其他线程都处于冻结状态。因此,任何需要正在运行的其他线程的调用都将失败。
- 输出至控制台的调用会以相对良性的方式失败,因为仅是没有输出。
- 进入死锁的概率很小,因为许多 C/C++
库函数(其中包括输入/输出和内存分配函数)需要调用受互斥保护的非可重入代码。
- 函数无法调用 或 exec(),并且它无法终止线程
如果这些限制的其中一个未满足,那么调试器将尝试进行恢复。但是,它无法保证要调试的应用程序的状态将不会以不可撤销的方式进行更改。