core 基本操作

1. 保存core dump文件

默认linux系统的core dump可能没有打开,因为core dump文件很大,会大量占用机器资源。为了保存core dump文件,需要运行前设置 ulimit -c unlimited
core文件会保存在当前目录下,并且只对当前终端有效,可以用命令修改core文件位置 sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t

2. backtrace辅助排查

线上服务一般占用内存较大,出core时,dump非常慢,gdb加载的时候也很慢。而大多数场景的core,结合堆栈和代码就可以确定。可以选择通过捕获信号、backtrace打印堆栈来辅助排查问题。

#include <signal.h>
#include <iostream>
#include <stdio.h>
#include <execinfo.h>

void handler(int sig) {
void *array[64];
int size = backtrace(array, 64);
std::cout << "Error: sig: " << sig << std::endl;
char** address = backtrace_symbols(array, size);

for (int i = 0; i < size; i++) {
  std::cout << i << " : " << address[i] << std::endl;
}
free(address);
}

void baz() {
::raise(SIGABRT);
}

void bar() {
baz();
}

void foo() {
bar();
}

int main(void) {
::signal(SIGSEGV, &handler);
::signal(SIGABRT, &handler);

foo();
return 0;
}

这个代码会捕获abort信号,并将堆栈打印到标准输出。
执行编译 g++ core_backtrace.cpp -o ba -ggdb -rdynamic
运行结果:

这种实现方式不能应用到线上。线上可以直接使用boost实现的方法来打印到文件中。

    #include <signal.h>
    ::signal(SIGSEGV, &my_signal_handler); //发SIGSEGV信号
    ::signal(SIGABRT, &my_signal_handler); //发SIGABRT信号
    //捕获处理信号
    #include <signal.h>
    #include <boost/stacktrace.hpp>
    void my_signal_handler(int signum) {
        ::signal(signum, SIG_DFL);
        boost::stacktrace::safe_dump_to("./backtrace.dump");
        ::raise(SIGABRT);
    }
posted @ 2021-10-29 17:40  我的娃会叫爸爸啦  阅读(245)  评论(0编辑  收藏  举报