Linux:如何调试 SIGSEGV?如何追溯错误来源?

标签 linux debugging trace dump segmentation-fault

我的 firefox 从今天开始就崩溃了。我没有对系统或 Firefox 配置进行任何更改。

我用
strace -ff -o dumpfile.txt firefox
追踪问题。帮助不大。

我在两个生成的进程转储中看到段错误, 但是我如何才能追踪他们的原因呢?

运行 10 秒后崩溃, strace 生成了 22MB 的数据。

这是输出的一个片段,您可以在中间看到实际的 SIGSEGV。:

read(19, "\372", 1)                     = 1
gettimeofday({1245590019, 542231}, NULL) = 0
read(3, "\6\0[Qmy\26\0\3\1\0\0Y\0\200\2\0\0\0\0\323\3A\0\323\3(\0\20\0\1\0", 4096) = 32
read(3, 0xf5c55058, 4096)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1245590019, 542813}, NULL) = 0
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=8, events=POLLIN|POLLPRI}, {fd=12, events=POLLIN|POLLPRI}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POL
read(3, 0xf5c55058, 4096)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1245590019, 543161}, NULL) = 0
gettimeofday({1245590019, 546672}, NULL) = 0
gettimeofday({1245590019, 546761}, NULL) = 0
read(3, 0xf5c55058, 4096)               = -1 EAGAIN (Resource temporarily unavailable)
gettimeofday({1245590019, 546936}, NULL) = 0
poll([{fd=4, events=POLLIN}, {fd=3, events=POLLIN}, {fd=8, events=POLLIN|POLLPRI}, {fd=12, events=POLLIN|POLLPRI}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POL
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"5\30\4\0006\21\200\2\266\n\200\2\17\0]\3\230\4\5\0007\21\200\0026\21\200\2\317\0\0\0"..., 1624}, {NULL, 0}, {"", 0}], 3) = 1624
poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\1\30\224Q\17\17\0\0\0\0\0\0\0\0\0\0000\235\273\0\0\0\0\0o\264Q\0\0\0\0\0"..., 4096) = 4096
read(3, "\375\240f\0\376\242j\0\377\261\200\0\271a+\0\271a+\0\377\261\200\0\376\252w\0\376\250s\0"..., 11356) = 11356
read(3, 0xf5c55058, 4096)               = -1 EAGAIN (Resource temporarily unavailable)
poll([{fd=3, events=POLLIN|POLLOUT}], 1, 4294967295) = 1 ([{fd=3, revents=POLLOUT}])
writev(3, [{"\230\32\7\0\1\21\200\2?\21\200\2\377\377\377\377\377\377\377\377\0\0\0\0\17\0\1\0015\10\4\0"..., 956}, {NULL, 0}, {"", 0}], 3) = 956
poll([{fd=3, events=POLLIN}], 1, 4294967295) = 1 ([{fd=3, revents=POLLIN}])
read(3, "\1\30\256Q\17\17\0\0\0\0\0\0\0\0\0\0000\235\273\0\0\0\0\0o\264Q\0\0\0\0\0"..., 4096) = 4096
read(3, "\375\240f\0\376\242j\0\377\261\200\0\271a+\0\271a+\0\377\261\200\0\376\252w\0\376\250s\0"..., 11356) = 11356
read(3, 0xf5c55058, 4096)               = -1 EAGAIN (Resource temporarily unavailable)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
unlink("/home/userrrr/.mozilla/firefox/mvbnkitl.default/lock") = 0
rt_sigaction(SIGSEGV, {SIG_DFL, ~[HUP INT QUIT ABRT BUS FPE KILL PIPE CHLD CONT TTOU URG XCPU WINCH RT_1 RT_2 RT_3 RT_4 RT_8 RT_11 RT_14 RT_17 RT_22], SA_NOCLDSTOP},
rt_sigprocmask(SIG_BLOCK, ~[ILL ABRT BUS FPE SEGV RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
open("/home/userrrr/.mozilla/firefox/mvbnkitl.default/minidumps/56b30367-5ee2-0495-32646b7f-59dc87e9.dmp", O_WRONLY|O_CREAT|O_EXCL, 0600) = 63
clone(child_stack=0xf5bfffe4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_UNTRACED) = 18929
waitpid(18929, NULL, __WALL) = 18929
open("/proc/18913/task", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 64
fstat64(64, {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
getdents64(64, /* 12 entries */, 1024)  = 368
ptrace(PTRACE_DETACH, 18913, 0, SIG_0)  = -1 ESRCH (No such process)
close(64)                               = 0
ftruncate(63, 91256)                    = 0
close(63)                               = 0
rt_sigprocmask(SIG_SETMASK, ~[KILL STOP RTMIN RT_1], ~[KILL STOP RTMIN RT_1], 8) = 0
time(NULL)                              = 1245590020
open("/home/userrrr/.mozilla/firefox/Crash Reports/LastCrash", O_WRONLY|O_CREAT|O_TRUNC, 0600) = 63
write(63, "1245590020", 10)             = 10

最佳答案

Ivan,你真正的问题是“我如何调试 SIGSEGV?”

strace 在这里很少能提供很好的帮助。 SIGSEGV 意味着应用程序试图取消引用(访问)内存中尚未分配的位置(或由于各种其他原因不允许取消引用)。它与 strace 捕获的系统调用事件无关的可能性很高。为了发现崩溃的原因,首先要了解正在取消引用的地址以及试图执行此操作的函数。调试器是完成此任务的合适工具。

这是您需要做的:

 gdb <your_app_name> <your_coredump_file>

在那里,分析最后执行的指令并使用“信息寄存器”,您将看到有问题的地址。使用“bt”命令,您将看到调用堆栈。通过向上遍历调用堆栈,您会发现错误地址是如何计算出来的。此地址计算中涉及的步骤之一是导致您出现问题的原因。

调试很有趣,这是深入研究它的好机会。一本好书或一些在线文章可以帮助你。谷歌离开,祝你好运!

关于Linux:如何调试 SIGSEGV?如何追溯错误来源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1023882/

相关文章:

linux - 通过扩展名删除文件的最佳方法是什么?

python - 等待调试器连接的 Visual Studio Code Python 超时

javascript - 使用 webpack 时如何在调试器中获取 javascript 变量

java - 正则表达式似乎对特殊字符无效(例如 +-.,!@#$%^&*;)

linux - 有没有一种方法可以使用不包含嵌套函数持续时间的 trace-cmd 输出函数持续时间?

azure - 我无法启动 Azure 诊断监视器

linux - tty 终端中的 Vim 颜色

php - 删除大量文件

c++ - 使用 liblttng 在 C++ 中自动插入跟踪点语句

linux - buddy.works管道cd到目录失败