在GDB中是否有与Windbg的"!process 0 7"相同的命令?
我想提取转储文件中的所有线程以及它们在GDB中的回溯."info threads"不输出堆栈跟踪.那么,有没有命令呢?
特定于Linux backtrace()并backtrace_symbols()允许您生成程序的调用跟踪.但是,它只打印功能地址,而不是我的程序的名称.如何让它们也打印出函数名?我试着编译程序-g以及-ggdb.下面的测试用例打印出来:
BACKTRACE ------------
./a.out() [0x8048616]
./a.out() [0x8048623]
/lib/libc.so.6(__libc_start_main+0xf3) [0x4a937413]
./a.out() [0x8048421]
----------------------
我希望前两个项目也显示函数名称,foo和main
码:
#include <execinfo.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
static void full_write(int fd, const char *buf, size_t len)
{
while (len > 0) {
ssize_t ret = write(fd, buf, len);
if ((ret == -1) && (errno != EINTR))
break;
buf += (size_t) ret;
len -= (size_t) ret;
}
}
void print_backtrace(void)
{
static const …Run Code Online (Sandbox Code Playgroud) 尝试使用其默认的当前行错误消息来调试PHP是非常糟糕的.如何在生成错误时让PHP生成回溯(堆栈跟踪)?
我目前正在寻找一种在Windows下从C代码(无C++)获取回溯信息的方法.
我正在构建一个跨平台的C库,带有引用计数内存管理.它还有一个集成的内存调试器,提供有关内存错误的信息(XEOS C Foundation Library).
发生故障时,将启动调试器,提供有关故障的信息以及所涉及的内存记录.

在Linux或Mac OS X上,我可以查找execinfo.h以便使用该backtrace功能,因此我可以显示有关内存故障的其他信息.
我在Windows上寻找同样的东西.
我已经看过如何在C中获取堆栈跟踪?在Stack Overflow上.我不想使用第三方库,所以CaptureStackBackTrace或者StackWalk函数看起来不错.
唯一的问题是我只是不知道如何使用它们,即使使用Microsoft文档.
我不习惯Windows编程,因为我通常在兼容POSIX的系统上工作.
对这些功能有什么解释,也许是一些例子?
编辑
我现在正在考虑使用这个CaptureStackBackTrace函数DbgHelp.lib,因为似乎开销有点少......
这是我到目前为止所尝试的:
unsigned int i;
void * stack[ 100 ];
unsigned short frames;
SYMBOL_INFO symbol;
HANDLE process;
process = GetCurrentProcess();
SymInitialize( process, NULL, TRUE );
frames = CaptureStackBackTrace( 0, 100, stack, NULL );
for( i = 0; i < frames; i++ )
{
SymFromAddr( process, ( DWORD64 )( …Run Code Online (Sandbox Code Playgroud) 我现在正在使用它:
error_log(serialize(debug_backtrace()));
Run Code Online (Sandbox Code Playgroud)
但我每次都必须对它进行反序列化.是否有更好的存储回溯的方法?
我正在为Android(仅限ARM)编写这个,但我相信通用Linux的原理也是如此.
我正在尝试从信号处理程序中捕获堆栈跟踪,以便我可以在应用程序崩溃时记录它.这就是我想出来的用法<unwind.h>.
初始化:
struct sigaction signalhandlerDescriptor;
memset(&signalhandlerDescriptor, 0, sizeof(signalhandlerDescriptor));
signalhandlerDescriptor.sa_flags = SA_SIGINFO;
signalhandlerDescriptor._u._sa_sigaction = signalHandler;
sigaction(SIGSEGV, &signalhandlerDescriptor, 0);
Run Code Online (Sandbox Code Playgroud)
代码本身:
struct BacktraceState
{
void** current;
void** end;
void* pc;
};
inline _Unwind_Reason_Code unwindCallback(struct _Unwind_Context* context, void* arg)
{
BacktraceState* state = static_cast<BacktraceState*>(arg);
state->pc = (void*)_Unwind_GetIP(context);
if (state->pc)
{
if (state->current == state->end)
return _URC_END_OF_STACK;
else
*state->current++ = reinterpret_cast<void*>(state->pc);
}
return _URC_NO_REASON;
}
inline size_t captureBacktrace(void** addrs, size_t max, unsigned long pc)
{
BacktraceState state = {addrs, addrs + max, …Run Code Online (Sandbox Code Playgroud) Call Trace包含以下条目:
[<deadbeef>] FunctionName+0xAB/0xCD [module_name]
[<f00fface>] ? AnotherFunctionName+0x12/0x40 [module_name]
[<deaffeed>] ClearFunctionName+0x88/0x88 [module_name]
Run Code Online (Sandbox Code Playgroud)
'?'是什么意思?在AnotherFunctionName之前标记?
神奇的咒语
LD_PRELOAD=/lib/libSegFault.so someapp
Run Code Online (Sandbox Code Playgroud)
someapp与libSegFault.so一起运行,提供有关SIGSEGV的回溯信息,如许多 不同的 地方所述.
除了使用类似signal(7)方法来SIGABRT调用SIGSEGV处理程序之外,还有一些方法可以让libSegFault为assert(3)失败提供回溯信息吗?
所以我试图找出哪些内核进程正在调用块驱动程序中的某些函数.我认为在C库中包含backtrace()可以让它变得简单.但是我无法加载回溯.
我复制了这个示例函数来显示回溯:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html
所有编译尝试都在一个地方或另一个地方发生错误,导致无法找到文件或未定义函数.
这是最接近的.
在Makefile中我放了编译器指令:
-rdynamic -I/usr/include
Run Code Online (Sandbox Code Playgroud)
如果我省略第二个,-I/usr/include,那么编译器报告它找不到所需的头文件execinfo.h.
接下来,在我想要进行回溯的代码中,我从示例中复制了该函数:
//trying to include the c backtrace capability
#include <execinfo.h>
void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
Run Code Online (Sandbox Code Playgroud)
我稍后在块驱动程序函数中调用此函数,其中发生错误的第一个符号.只是:
show_stackframe();
Run Code Online (Sandbox Code Playgroud)
所以当我编译它时,会出现以下错误:
user@slinux:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
from /usr/include/execinfo.h:22,
from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: …Run Code Online (Sandbox Code Playgroud) 我试图在C++程序中的回溯中找到确切的调用行.现在我正在使用这些行(来自backtrace的手册页)来获取跟踪:
void *bt_buffer[1000];
char **bt_strings;
int bt_nptrs = backtrace(bt_buffer, 1000);
bt_strings = backtrace_symbols(bt_buffer, bt_nptrs);
Run Code Online (Sandbox Code Playgroud)
在bt_strings中,我找到了表单的行
./prog() [0x402e42]
Run Code Online (Sandbox Code Playgroud)
现在我取地址(十六进制字符串)并将其提供给addr2line.这有时会导致明显错误的行号.互联网搜索让我看到这篇文章,其中显示了这一点
readelf -wl ./prog
Run Code Online (Sandbox Code Playgroud)
表示该行的确实位置,或者表示该符号移动到当前行的行数.
编辑:这种情况发生在我编译时-g -O0,即明确没有优化.编译器gcc 4.6.3是否有我错过的另一个编译器标志?
我的问题如下:我需要自动执行此操作.我需要我的程序来创建一个回溯(完成),提取文件(完成)和行号(失败).
我当然可以调用readelf和解析输出,但这并不合适,因为输出因符号而异,具体取决于具体发生的情况.有时符号的地址在一行中,而在下一行中有关行偏移的信息......
总结一下:
有没有一种优雅的方法可以在运行时从程序中的回溯中获取函数调用的确切行号?
编辑:示例代码:
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <execinfo.h>
#include <iostream>
#include <stdlib.h>
void show_backtrace()
{
// get current address
void* p = __builtin_return_address(0);
std::cout << std::hex << p << std::endl;
// get callee addresses
p = __builtin_return_address(1);
std::cout << std::hex …Run Code Online (Sandbox Code Playgroud)