Linux遇到Aborted (core dumped)

1、问题描述

在这里插入图片描述
或出现:
在这里插入图片描述

2、关于Core Dump的分析

2.1 什么是Core Dump

  • Core的意思是内存, Dump的意思是扔出来, 堆出来。在开发(或使用)一个程序时,有时程序莫名其妙的down了, 却没有任何的提示(有时候会提示core dumped)。虽然系统没事,但我们下次仍可能遇到相同的问题。这时候可以查看一下有没有形如core.PID的core文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的,让我们或是 debugger 做为参考。这个动作就叫作 core dump。
  • core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump。简而言之,进程异常终止,进程用户空间的数据就会被写到磁盘

2.2 为何有时程序Down了,却没生成 Core文件。

  • 有时候程序down了, 不像编译错误一样会提示到文件一行,而是没有任何信息。一种办法是用gdb的step(linux下调试工具gdb是很强大的调试器), 一步一步寻找,但要step一个上万行的代码让人难以想象。 我们还有更好的办法,这就是core file。
  • 但是core文件却没有生成,这是因为core.PID的core文件的生成跟你当前系统的环境设置有关系,系统默认core文件的大小为0(注意core file size (blocks, -c) 0 这行,这表示的是分配给core文件的长度(单位为字节,一个块的大小要分系统而定了),为0肯定是不得行的,那就修改之
    在这里插入图片描述
  • 则需要用ulimit命令查看和修改core文件的大小,使用ulimit -a查看大小,使用 ulimit -c unlimited表示对core文件不做限制 或 使用ulimit -c 1024 对core文件分配1024个字节。
    在这里插入图片描述
  • 然后再运行程序便成生成core.PID的core文件(core文件生成的位置一般和运行程序的路径相同, 文件名一般为core.进程号)。

2.3 如何使用core文件?

发生core dump之后,使用gdb查看core文件的内容, 以定位文件中引发core dump的行,在在Linux下,查看core文件中的出错堆栈信息有二种方式,使用:gdb -c core.pid program_namegdb [program_name] [core.pid]可以进入gdb模式:

  • 在进入gdb后输入where并回车,就可以指出是在哪一行被Down掉,在哪个函数内,由谁调用等等。
  • 在进入gdb后输入 bt,用bt命令查看backtrace以检查发生程序运行到哪里,来定位core dump的文件->行。

3、多种示例

3.1 batch_size过大导致的

Aborted(core dumped)

3.2 线程被谋杀, 被谋杀者所在线程会抛出一个异常

Cancellation & C++ Exception

3.3 关于 pure virtual method called terminate called without an active exception 解决方案

对于多线程的程序,这个错误的主要原因是当前对象已经被销毁或者正在被销毁,但是其又在被调用,导致了冲突。

3.4 pure virtual method called

记录一个编写多线程程序时遇到的运行时错误:pure virtual method called

起因是写了一个多线程基类,里面有一个纯虚函数run,子类继承了这个run,重点就在纯虚函数上,因为是在基类中构造时创建的线程,线程创建后直接运行run函数,而这时子类尚未构造,所以run函数此时依旧是纯虚函数,就会出现pure virtual method called这个错误而终止运行,感谢http://bbs.youkuaiyun.com/topics/340224117这个帖子里的大神们

参考1:什么是Core Dump?
参考2:Segmentation fault (core dumped)的解决办法
参考3:关于Segmentation fault (core dumped)几个简单问题
参考4:关于core文件
参考5:ubuntu查看core dumped的详细错误原因

### 多线程定时器导致 'Aborted (core dumped)' 的原因及解决方案 当多线程应用程序中使用定时器时,如果发生 `Aborted (core dumped)` 错误,通常表明程序遇到了未捕获的信号(如 SIGSEGV 或 SIGABRT),这可能是由于内存访问违规、非法操作或其他异常情况引起的。以下是可能的原因及其对应的解决方案: #### 可能原因 1:信号处理不当 在 Linux 中,定时器可能会触发特定的信号(如 SIGALRM)。如果没有正确设置信号处理器或信号被阻塞,则可能导致程序崩溃。 - **解决方案**: 使用 `sigaction` 设置自定义信号处理器来捕获并安全地处理这些信号[^2]。 ```c #include <signal.h> #include <stdio.h> void signal_handler(int signum) { printf("Signal %d received\n", signum); } int main() { struct sigaction sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGALRM, &sa, NULL) == -1) { perror("sigaction"); return 1; } alarm(5); // Set a timer to trigger after 5 seconds. while (1) { } } ``` --- #### 可能原因 2:资源竞争条件 多个线程共享数据结构时,可能存在竞态条件(race condition),尤其是在定时器回调函数修改全局变量或共享资源时。 - **解决方案**: 使用互斥锁(mutex)保护共享资源,防止并发访问引发问题[^3]。 ```c #include <pthread.h> #include <stdio.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int shared_variable = 0; void* thread_function(void* arg) { pthread_mutex_lock(&mutex); shared_variable++; printf("Shared variable updated: %d\n", shared_variable); pthread_mutex_unlock(&mutex); return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_function, NULL); pthread_join(tid, NULL); return 0; } ``` --- #### 可能原因 3:核心转储文件生成失败 如果系统未能成功生成核心转储文件,可能是因为权限不足或资源限制过高。这种情况下,即使程序崩溃也无法提供足够的诊断信息。 - **解决方案**: 调整系统的 ulimit 配置以及 `/proc/sys/kernel/core_pattern` 文件路径,确保核心转储功能正常启用。 ```bash ulimit -c unlimited # 允许无限制的核心转储文件大小 echo "/tmp/core-%e.%p" > /proc/sys/kernel/core_pattern # 自定义核心转储文件名模式 ``` --- #### 可能原因 4:定时器超时逻辑错误 某些情况下,定时器的超时逻辑可能出现设计缺陷,例如重复注册定时器或忘记取消已过期的定时器实例。 - **解决方案**: 确保每次创建新定时器前都检查其当前状态,并清理不再使用的旧定时器实例。 ```c #include <time.h> #include <stdlib.h> struct itimerspec its; timer_t timerid; // 初始化定时器... if (timer_settime(timerid, 0, &its, NULL) != 0) { perror("Failed to set timer time"); exit(EXIT_FAILURE); } ``` --- ### 总结 上述四种原因是多线程环境中定时器出现问题的主要因素之一。通过合理配置信号处理器、同步机制、系统环境以及仔细审查定时器管理代码,可以有效减少甚至完全消除此类错误的发生概率。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还能坚持

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值