C++ 获取 Linux x64 "Segmentation Fault"的文件名和行号
C++ Get File Name and Line Number of "Segmentation Fault" Linux x64
不运行GDB,只运行程序本身
编辑:我已经看过这样的程序,但我不知道如何做到自己:(
Tommie解决了这个问题。
我已经把他的答案从GDB中分离出来,使用<execinfo.h>
中有点标准的backtrace
实用程序。
static void dumpstack(void){
static void *backbuf[ 50 ];
int levels;
levels = backtrace( backbuf, 50 );
backtrace_symbols_fd( backbuf, levels, STDERR_FILENO );
return;
}
你可以试着打开一个文件,而不是写STDERR_FILENO
,但我会避免在崩溃的过程中这样繁重的工作。
在我的系统上,输出看起来像这样:
Shadow:code dkrauss$ ./dumpy
0 dumpy 0x0000000100000d81 dumpstack + 25
1 dumpy 0x0000000100000d18 signal_handler + 47
2 libSystem.B.dylib 0x00007fff86b1766a _sigtramp + 26
3 ??? 0x0000000000000000 0x0 + 0
4 dumpy 0x0000000100000a18 start + 52
FATAL: Segmentation Fault
所以,它没有给出文件名+行号,但它给出了函数名+代码偏移量,你可以很容易地翻译。
嗯…你可以试试这样做…
struct sigaction g_sigact;
void panic(const char *fmt, ...){
char buf[PANICBUF_LEN];
va_list argptr;
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
fprintf(stderr, "%sn", buf);
exit(-1);
}
void init_signals(void){
g_sigact.sa_handler = signal_handler;
sigemptyset(&g_sigact.sa_mask);
g_sigact.sa_flags = 0;
sigaction(SIGINT, &g_sigact, (struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask, SIGSEGV);
sigaction(SIGSEGV, &g_sigact, (struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask, SIGBUS);
sigaction(SIGBUS, &g_sigact, (struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask, SIGQUIT);
sigaction(SIGQUIT, &g_sigact, (struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask, SIGHUP);
sigaction(SIGHUP, &g_sigact, (struct sigaction *)NULL);
sigaddset(&g_sigact.sa_mask, SIGKILL);
sigaction(SIGKILL, &g_sigact, (struct sigaction *)NULL);
}
static void signal_handler(int sig){
if (sig == SIGHUP) g_keepRunning = 0;
if (sig == SIGSEGV || sig == SIGBUS){
dumpstack();
panic("FATAL: %s Faultn", (sig == SIGSEGV) ? "Segmentation" : ((sig == SIGBUS) ? "Bus" : "Unknown"));
}
if ((sig == SIGQUIT || (sig == SIGKILL) || (sig == SIGINT)) ;
}
static void dumpstack(void){
/* Got this routine from http://www.whitefang.com/unix/faq_toc.html
** Section 6.5. Modified to redirect to file to prevent clutter
*/
char dbx[160];
sprintf(dbx, "echo -ne 'detachn' | gdb --eval-command=where --pid=%d > %d.dump", getpid(), getpid());
system(dbx);
return;
}
当分割错误被捕获时,dumpstack
被调用并打印最近的堆栈跟踪,直到它分割错误并被重定向到具有进程数值pid的文件....
为什么你不想运行gdb?如果您使用它,您可以很容易地检测到分段故障的位置。
相关文章:
- 从命令行c++发送文本文件名
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 当Microsoft文档仅包含 C# 示例时,如何查找 C++ 包含文件名
- 如何在CPP的给定目录中列出UTF编码的文件名?
- 在Visual Studio 2019中保存时ReadDirectoryChangesW文件名的问题
- C++:在Windows中浏览名称中带有点的文件名
- 我在 ifstream input_file(文件名)行中收到错误"no matching function to call";
- 不带预处理器的调用方法/文件的文件名/行号
- 在 C++ 中为文件名添加时间戳
- 为什么当我在 std::string 中打开文件名的 fstream 时出现"no matching function"错误?
- 如何将文件名作为参数传入并正确打开?
- 如何在目录及其子文件夹中构建文件名字符串向量?
- 要求用户输入C++输出文件名
- 从Arduino SD卡模块到Array的文件名
- 如何使用打印到 PDF 打印机在 MFC 和 CView 中以编程方式打印而不提示输入文件名?
- C++ 从变量导入文件名
- 从 Makefile 中的 $@ 获取文件名
- VSCode C++调试文件名中包含中文字符的文件时插件损坏
- _CrtSetAllocHook - 空文件名和行号参数