代码之家  ›  专栏  ›  技术社区  ›  Jeremy Mullin

从进程内部转储Linux核心文件的好方法是什么?

  •  12
  • Jeremy Mullin  · 技术社区  · 16 年前

    我们有一个服务器(用C和C++编写),当前捕获一个SeGV并将一些内部信息转储给一个文件。我想生成一个核心文件,并在我们捕获SEGV时将其写入磁盘,这样我们的支持代表和客户就不必对ulimit大惊小怪,然后等待崩溃再次发生,以便获得核心文件。我们过去使用过abort函数,但它受ulimit规则的约束,没有帮助。

    我们有一些旧代码读取/proc/pid/map并手动生成一个核心文件,但是它已经过时了,而且看起来不太可移植(例如,我猜想它在我们的64位构建中不会工作)。在Linux进程中生成和转储核心文件的最佳方法是什么?

    8 回复  |  直到 13 年前
        1
  •  9
  •   Phillip Whelan    16 年前

    Google有一个库,可以从一个正在运行的进程内部生成coredump google-coredumper . 这应该忽略ulimit和其他机制。

    生成核心文件的调用的文档是 here . 根据文档,在信号处理程序中生成一个核心文件似乎是可行的,尽管并不保证它总是有效的。

        2
  •  5
  •   Community Lee Campbell    7 年前

    我看见了 pmbrett's post 我想“嘿,很酷”,但在我的系统中找不到这个实用程序(Gentoo)。

    所以我做了一些提示,发现gdb有这个选项。

    gdb --pid=4049 --batch -ex gcore

    对我来说似乎工作得很好。

    不过,它并不是很有用,因为它捕获了当时使用的最低级别的函数,但它在这之外仍然做得很好(不受内存限制,使用它转储了一个火狐进程的350m快照)

        3
  •  4
  •   user41716    16 年前

    尝试使用linux命令gcore

    用法:gcore[-o filename]pid

    您需要使用system(或exec)和getpid()来构建正确的命令行,从您的进程中调用它。

        4
  •  3
  •   activout.se    16 年前

    处理这种情况的一些可能的解决方案:

    1. 修复ULIMIT!!!!
    2. 接受你没有得到一个核心文件并在gdb中运行,脚本化为在sigsegv上执行“thread all apply bt”
    3. 接受您没有获得核心文件,并且从应用程序中获取了堆栈跟踪。这个 Stack Backtracing Inside Your Program 这篇文章很旧,但现在也有可能。
        5
  •  1
  •   Perry Lorier    16 年前

    还可以使用setrlimit(2)从程序中更改ulimit()。就像ulimit shell命令一样,这可以降低限制,或者尽可能地提高限制。在启动时,setrlimit()允许核心转储,这样就可以了。

        6
  •  1
  •   Jay Haynberg    13 年前

    例如,我假设您有一个信号处理程序来捕获SEGV,并执行类似于打印消息和调用_exit()的操作。(否则,您将首先拥有一个核心文件!)你可以做如下的事情。

    void my_handler(int sig)
    {
       ...
       if (wantCore_ && !fork()) {
          setrlimit(...);  // ulimit -Sc unlimited
          sigset(sig, SIG_DFL);  // reset default handler
          raise(sig);  // doesn't return, generates a core file
       }
       _exit(1);
    }
    
        7
  •  0
  •   Joe    15 年前

    系统(“压井-6”)

    如果你还在找东西,我会试试的

        8
  •  0
  •   Yusuf Khan    14 年前

    使用backtrace和backtrace-symbols glibc调用获取跟踪,请记住backtrace-symbols在内部使用malloc,如果堆损坏,它可能会失败。