AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1349047
Accepted
Gabriel Staples
Gabriel Staples
Asked: 2021-06-30 20:50:56 +0800 CST2021-06-30 20:50:56 +0800 CST 2021-06-30 20:50:56 +0800 CST

我在哪里可以找到核心转储文件,如何同时查看和分析回溯(堆栈跟踪)?

  • 772

当我在 Ubuntu 20.04 上运行 C 程序时,出现以下运行时错误:

Segmentation fault (core dumped)

我真的需要找到并查看该core文件,但我无法在任何地方找到它。它在哪里,如何查看其中的回溯?

debugging
  • 2 2 个回答
  • 25889 Views

2 个回答

  • Voted
  1. Best Answer
    Gabriel Staples
    2021-06-30T20:50:56+08:002021-06-30T20:50:56+08:00

    在 Ubuntu 20.04 中测试。

    1.启用核心文件

    首先,运行ulimit -c以查看系统上核心文件的最大允许大小。在我的 Ubuntu 20.04 上,我的返回0,这意味着无法创建核心文件。

    ulimit --help显示 的含义-c:

    -c  the maximum size of core files created
    

    因此,将允许的核心文件大小设置为unlimited,如下所示。请注意,我认为这仅适用于您在其中运行它的一个终端,并且我认为它不会在重新启动后持续存在,因此您必须在每次想要创建核心文件时运行它,并且在每个终端中运行它工作:

    # set max core dump file size to unlimited
    ulimit -c unlimited
    # verify it is now set to "unlimited"
    ulimit -c
    

    而已!现在,运行您的程序,如果它崩溃并执行“核心转储”,它会将核心作为core文件转储到您调用可执行文件时所在的同一目录中。该文件的名称只是“核心”。

    2.查看gdb中的回溯

    为了在核心文件中看到有用的信息,您应该已经构建了带有调试符号的 C 或 C++ 程序。如果没有调试符号,您只能看到被调用函数的地址,而不是实际名称或行号。

    在 gcc 中,用于-ggdb -O0打开为NU e uggerg优化的 debu 符号。您也可以使用,等,但最好。我们真的需要优化级别 0 ( ) 吗?是的,是的,我们这样做。在这里查看我的答案:堆栈溢出:编译器的选项和选项之间有什么区别?gdb Gdb-g -O0-g3 -O0-ggdb -O0-O0-O0-Og

    C 和 C++ 中的构建和运行命令示例:因此,您在 C 或 C++ 中的完整构建和运行命令可能如下所示:

    # C build and run command for "hello_world.c"
    gcc -Wall -Wextra -Werror -ggdb -O0 -std=c11 -o hello_world hello_world.c \
    && ./hello_world
    
    # C++ build and run command for "hello_world.c"
    g++ -Wall -Wextra -Werror -ggdb -O0 -std=c++17 -o hello_world hello_world.c \
    && ./hello_world
    

    像这样打开核心文件gdb:

    gdb path/to/my/executable path/to/core
    

    假设您刚刚运行path/to/my/executable,那么该core文件将位于您转储核心时所在的同一目录中,因此您可以运行以下命令:

    gdb path/to/my/executable core
    

    在gdb中,查看回溯(崩溃时的函数调用堆栈):

    bt
    # or (exact same command)
    where
    
    # OR (for even more details, such as seeing all arguments to the functions--
    # thanks to Peter Cordes in the comments below)
    bt full
    
    # For gdb help and details, see:
    help bt
    # or
    help where
    

    重要提示:发生核心转储时,它不会自动用新文件覆盖core当前目录中的任何预先存在的文件,因此您必须在程序崩溃时手动删除旧core文件并rm core生成新的核心文件,以便始终拥有最新的核心文件进行分析。

    3. 试试看

    1. 在终端中,运行sleep 30以启动一个休眠 30 秒的进程。
    2. 在它运行时,按Ctrl+\强制进行核心转储。您现在将core在您所在的目录中看到一个文件。
    3. 由于我们没有包含调试符号的可执行文件,因此我们将只打开 gdb 中的核心文件,而不是带有符号的可执行文件 + 核心文件。因此,运行gdb -c core以打开刚刚由强制崩溃创建的核心文件。
    4. 你会看到这个。sleep 30请注意,当核心转储发生时, 它知道您调用了 ( ) 的命令:
      Core was generated by `sleep 30'.
      Program terminated with signal SIGQUIT, Quit.
      #0  0x00007f93ed32d334 in ?? ()
      (gdb) 
      
    5. 运行bt或where查看回溯。你会看到这个:
      (gdb) bt
      #0  0x00007f93ed32d334 in ?? ()
      #1  0x000000000000000a in ?? ()
      #2  0x00007f93ed2960a5 in ?? ()
      #3  0x0000000000000000 in ?? ()
      (gdb)
      
    6. 这些是调用堆栈上调用的函数的地址。如果您打开了调试符号,您会看到更多信息,包括函数名称和行号,如下所示(从我的 C 程序中提取):
      #10 0x00007fc1152b8ebf in __printf (format=<optimized out>) at printf.c:33
      #11 0x0000562bca17b3eb in fast_malloc (num_bytes=1024) at src/fast_malloc.c:225
      #12 0x0000562bca17bb66 in malloc (num_bytes=1024) at src/fast_malloc.c:496
      

    4.忘掉core文件,直接在gdb中运行程序到崩溃点!

    正如@Peter Cordes 在下面的评论中所说,您也可以直接在 gdb 中运行程序,让它在那里崩溃,因此您无需在事后打开核心文件!他说:

    这些 GDB 命令并不特定于核心文件,只要您在断点处停止,它们就会起作用。如果你有一个可重现的崩溃,在 GDB 下运行你的程序通常更容易/更好(比如gdb ./a.out),所以 GDB 将把进程放在内存中而不是核心文件中。主要优点是您可以在崩溃之前的某处设置断点或观察点,并单步查看正在发生的事情。或者使用 GDB 的记录工具,您也许可以退后一步,看看是什么导致了崩溃,但这可能是不稳定的、缓慢的和内存密集型的。

    如上所述,您应该已经编译了带有调试符号并使用优化级别 0 的程序,使用-ggdb -O0. 请参阅上面的 C 和 C++ 中的完整示例构建和运行命令。

    现在在 gdb 中运行程序:

    # Open the executable in gdb
    gdb path/to/my/executable
    # Run it (if it's still crashing, you'll see it crash)
    r 
    # View the backtrace (call stack)
    bt  
    # Quit when done 
    q
    

    如果您需要手动将回溯记录到日志文件以供以后分析,您可以这样做(改编自我的eRCaGuy_dotfiles 存储库中的注释):

    set logging file gdb_log.txt
    set logging on
    set trace-commands on
    show logging     # prove logging is on
    flush
    set pretty print on
    bt               # view the backtrace
    set logging off  
    show logging     # prove logging is back off
    

    完毕!您现在已将 gdb 回溯保存在文件“gdb_log.txt”中。

    参考:

    1. [我需要的答案就在这个问题本身] https://stackoverflow.com/questions/2065912/core-dumped-but-core-file-is-not-in-the-current-directory
    2. https://stackoverflow.com/questions/5115613/core-dump-file-analysis
    3. https://stackoverflow.com/questions/8305866/how-do-i-analyze-a-programs-core-dump-file-with-gdb-when-it-has-command-line-pa/30524347#30524347
    4. [非常有用的信息,包括。强制核心转储的Ctrl+技巧!] https://unix.stackexchange.com/questions/277331/segmentation-fault-core-dumped-to-where-what-is-it-and-why/409776#409776\
    5. [以上答案引用] https://unix.stackexchange.com/questions/179998/where-to-search-for-the-core-file-generated-by-the-crash-of-a-linux-application /180004#180004
    6. [答案在问题本身]在哪里可以找到 ubuntu 16.04LTS 中的核心转储?
    7. [我的回答] Stack Overflow:编译器的选项和选项有什么区别?-O0-Og

    额外阅读要做

    1. [我仍然需要学习和尝试] 如何使用LD_PRELOAD:gdbhttps: //stackoverflow.com/questions/10448254/how-to-use-gdb-with-ld-preload
    • 23
  2. guyr
    2022-01-26T17:26:13+08:002022-01-26T17:26:13+08:00

    通过搜索找到。我正在运行 Ubuntu Mate 21.10。对于那些运行较晚型号 Ubuntu 的用户,apport将在/var/lib/apport/coredump.

    如果找不到核心转储文件,cat /var/log/apport.log. 当我这样做时,我看到:

    executable does not belong to a package, ignoring
    called for pid 5545, signal 11, core limit 0, dump mode 1
    

    注意核心限制 0,这意味着不会生成核心转储文件。所以,我运行了这篇文章 ( ulimit -c unlimited) 中显示的命令,这次apport.log显示的是:

    writing core dump to core._my_prog.1000.e43b2f33-4708-438c-a7d7-05062f381382.5650.795448 (limit: -1)
    

    我在当前目录或包含可执行文件的目录中找不到这个,所以我在整个系统上进行了查找,并在/var/lib/apport/coredump.

    • 9

相关问题

  • 我有硬件检测问题,我需要查看哪些日志?

  • 当我的系统死机时,如何确定发生了什么并定位问题?

  • 使用 gdb 调试 php

  • 在命令行工具中打印编号参数

  • 使用 sysprof 分析股票 Ubuntu 内核:如何?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve