Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;在gcc中的SIGSEGV期间,程序不处理任何函数调用或printf_C++_Gcc_Segmentation Fault_Backtrace - Fatal编程技术网

C++ C++;在gcc中的SIGSEGV期间,程序不处理任何函数调用或printf

C++ C++;在gcc中的SIGSEGV期间,程序不处理任何函数调用或printf,c++,gcc,segmentation-fault,backtrace,C++,Gcc,Segmentation Fault,Backtrace,我在将堆栈跟踪输出获取到stderr或转储到日志文件时遇到问题。我正在使用gcc编译器(4.4.3)运行Kubuntu10.04中的代码。问题在于,在正常运行模式下(无gdb),程序除了“分段故障”外,不输出任何内容。我希望像下面的打印语句一样输出回溯输出。当我用我的应用程序运行gdb时,它会出现printf/fprintf/(函数调用)语句,然后由于以下语句而崩溃: 669 { (gdb) 670 printf("Testing for stability.\n"); (

我在将堆栈跟踪输出获取到stderr或转储到日志文件时遇到问题。我正在使用gcc编译器(4.4.3)运行Kubuntu10.04中的代码。问题在于,在正常运行模式下(无gdb),程序除了“分段故障”外,不输出任何内容。我希望像下面的打印语句一样输出回溯输出。当我用我的应用程序运行gdb时,它会出现printf/fprintf/(函数调用)语句,然后由于以下语句而崩溃:

669     {
(gdb) 
670       printf("Testing for stability.\n");
(gdb) 

Program received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff68b1f45 in puts () from /lib/libc.so.6
奇怪的是,如果我在崩溃的同一个文件中调用一个函数,它就可以正常工作并正确输出。但如果程序在该文件之外的函数中崩溃,则不会打印任何输出。 因此,不会处理printf或文件转储语句或函数调用。我正在使用以下示例代码:

void bt_sighandler(int sig, siginfo_t *info,
               void *secret) {

void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
ucontext_t *uc = (ucontext_t *)secret;

/* Do something useful with siginfo_t */
if (sig == SIGSEGV)
  printf("Got signal %d, faulty address is %p, "
       "from %p\n", sig, info->si_addr, 
       uc->uc_mcontext.gregs[0]);
else
  printf("Got signal %d#92; \n", sig);

trace_size = backtrace(trace, 16);
/* overwrite sigaction with caller's address */
trace[1] = (void *) uc->uc_mcontext.gregs[0];

messages = backtrace_symbols(trace, trace_size);
/* skip first stack frame (points here) */
printf("[bt] Execution path:#92; \n");
for (i=1; i<trace_size; ++i)
  printf("[bt] %s#92; \n", messages[i]);

exit(0);
}


int main() {

/* Install our signal handler */
struct sigaction sa;

sa.sa_sigaction = (void *)bt_sighandler;
sigemptyset (&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;

sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGUSR1, &sa, NULL);
/* Do something */
printf("%d#92; \n", func_b());
}
void bt\u signandler(int-sig,siginfo\u t*info,
无效*秘密){
void*trace[16];
字符**消息=(字符**)空;
int i,跟踪大小=0;
ucontext_t*uc=(ucontext_t*)秘密;
/*使用siginfo\u t做一些有用的事情*/
if(sig==SIGSEGV)
printf(“获取信号%d,错误地址为%p,”
“从%p\n”,信号,信息->si_地址,
uc->uc mcontext.gregs[0]);
其他的
printf(“获取信号%d#92;\n”,sig);
trace_size=回溯(trace,16);
/*用呼叫者的地址覆盖sigaction*/
trace[1]=(void*)uc->uc_mcontext.gregs[0];
消息=反向跟踪符号(跟踪、跟踪大小);
/*跳过第一个堆栈帧(此处的点)*/
printf(“[bt]执行路径:#92;\n”);

对于(i=1;i您应该在信号处理程序中做的很少,原则上只访问sig_atomic_t类型的变量和易失性数据

执行I/O绝对是不可能的。有关gcc,请参阅本页:


在信号处理程序中,您应该做的很少,原则上只访问sig_原子类型的变量和易失性数据

执行I/O绝对是不可能的。有关gcc,请参阅本页:


尝试使用更简单的函数,如strcat()和write()。

尝试使用更简单的函数,如strcat()和write()。

不幸的是,在SIGSEGV处理程序中,您无法可靠地执行任何操作。请这样考虑:您的程序有严重错误及其状态(包括系统级状态,如堆)处于不一致的状态

在这种情况下,您不能期望操作系统神奇地修复堆和它需要的其他内部结构,以便能够在信号处理程序中执行任意代码


如果SEGV发生在您自己的代码中,那么好的解决方案是使用核心并修复根本问题。如果核心发生在其他代码中,例如通过共享库,我建议将该代码隔离在一个完全独立的二进制文件中,并在两个二进制文件之间进行通信。如果库崩溃,则您的主程序不会崩溃。

不幸的是,您需要只是在SIGSEGV处理程序中无法可靠地执行很多操作。请这样考虑:您的程序有严重错误,并且其状态(包括系统级状态,如堆)处于不一致状态

在这种情况下,您不能期望操作系统神奇地修复堆和它需要的其他内部结构,以便能够在信号处理程序中执行任意代码


如果SEGV发生在您自己的代码中,那么好的解决方案是使用核心并修复根本问题。如果核心发生在其他代码中,例如通过共享库,我建议将该代码隔离在一个完全独立的二进制文件中,并在两个二进制文件之间进行通信。那么如果库崩溃,您的主程序不会崩溃。

有什么原因吗当应用程序崩溃时,您不能使用valgrind?

有什么原因不能使用valgrind吗?

Linux创建一个核心转储,其中包含应用程序崩溃时的状态。可以使用gdb检查核心文件

如果未创建核心文件,请尝试使用更改核心文件大小

ulimit -c unlimited
在同一个shell中并且在程序启动之前。 核心文件的名称通常为core.PID,其中PID是程序的PID。 核心文件通常放在/tmp或启动程序的目录中

有关core文件的更多信息,请参见core手册页。使用

man core

阅读手册页。

当应用程序崩溃时,Linux创建一个核心转储,其中包含应用程序崩溃时的状态。可以使用gdb检查核心文件

如果未创建核心文件,请尝试使用更改核心文件大小

ulimit -c unlimited
在同一个shell中并且在程序启动之前。 核心文件的名称通常为core.PID,其中PID是程序的PID。 核心文件通常放在/tmp或启动程序的目录中

有关core文件的更多信息,请参见core手册页。使用

man core

阅读手册页。

我设法让它部分工作。实际上我是在“sudo”模式下运行应用程序。在用户模式下运行它会给我调用堆栈。但是在用户模式下运行会禁用硬件加速(nvidia图形驱动程序)。为了解决这个问题,我将自己添加到“视频”组,这样我就可以访问/dev/nvidia0&/dev/nvidiactl。但是,当我获得访问权限时,堆栈不再生成。只有当我处于用户模式且硬件加速被禁用时,堆栈才会出现。但如果没有硬件加速,我无法运行我的应用程序(意味着一些重要功能将被禁用)。如果有人有任何想法,请告诉我


谢谢。

我设法让它部分工作。实际上我是在“sudo”模式下运行应用程序。在用户模式下运行它会给我调用堆栈。但是在用户模式下运行会禁用硬件加速(nvidia图形驱动程序)。为了解决这个问题,我将自己添加到“video”组中,这样我就可以访问/dev/nvidia0&/dev/nvidiactl。但是,当我获得访问权限时,堆栈无法访问