【问题标题】:Where to look when a daemonized version of a program crashes?当程序的守护程序版本崩溃时在哪里查看?
【发布时间】:2016-04-12 16:26:10
【问题描述】:

我有一个 C++ 程序,它接收流媒体音乐并播放它。我可以通过 shell 运行程序并连接它运行,它运行得很好。我可以将音频流式传输到它并发送东西给它,但它不会崩溃。但是,当我将它守护并运行 fork 代码时,它会在一点点流式传输后意外崩溃。我尝试使用 gdb 来调试它,但它并没有给出太多的输出。

./bin/sonar -d ; sleep 1 ; gdb ./bin/sonar $(cat sonar.pid )
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /var/sonar/bin/sonar...done.
Attaching to program: /var/sonar/bin/sonar, process 4050
Reading symbols from /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libcofi_rpi.so
Reading symbols from /var/sonar/bin/../lib/libboost_system.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_system.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_chrono.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_chrono.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_timer.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_timer.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_iostreams.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_iostreams.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_thread.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_thread.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_log_setup.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_log_setup.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_log.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_log.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_filesystem.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_filesystem.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_atomic.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_atomic.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_date_time.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_date_time.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libboost_regex.so.1.60.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libboost_regex.so.1.60.0
Reading symbols from /var/sonar/bin/../lib/libopus.so.0...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libopus.so.0
Reading symbols from /var/sonar/bin/../lib/libmysql.so.16...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libmysql.so.16
Reading symbols from /var/sonar/bin/../lib/libmysqlpp.so.3...(no debugging symbols found)...done.
Loaded symbols for /var/sonar/bin/../lib/libmysqlpp.so.3
Reading symbols from /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.0.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.0.0
Reading symbols from /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libssl.so.1.0.0
Reading symbols from /usr/lib/arm-linux-gnueabihf/libasound.so.2...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libasound.so.2
Reading symbols from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
Reading symbols from /lib/arm-linux-gnueabihf/libm.so.6...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libm-2.19.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libm.so.6
Reading symbols from /lib/arm-linux-gnueabihf/libgcc_s.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/arm-linux-gnueabihf/libgcc_s.so.1
Reading symbols from /lib/arm-linux-gnueabihf/libpthread.so.0...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libpthread-2.19.so...done.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0x749ff450 (LWP 4054)]
[New Thread 0x75358450 (LWP 4053)]
[New Thread 0x75b58450 (LWP 4052)]
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libpthread.so.0
Reading symbols from /lib/arm-linux-gnueabihf/libc.so.6...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libc-2.19.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libc.so.6
Reading symbols from /lib/arm-linux-gnueabihf/librt.so.1...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/librt-2.19.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/librt.so.1
Reading symbols from /lib/arm-linux-gnueabihf/libbz2.so.1.0...(no debugging symbols found)...done.
Loaded symbols for /lib/arm-linux-gnueabihf/libbz2.so.1.0
Reading symbols from /lib/arm-linux-gnueabihf/libz.so.1...(no debugging symbols found)...done.
Loaded symbols for /lib/arm-linux-gnueabihf/libz.so.1
Reading symbols from /lib/arm-linux-gnueabihf/libdl.so.2...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libdl-2.19.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libdl.so.2
Reading symbols from /lib/ld-linux-armhf.so.3...(no debugging symbols found)...done.
Loaded symbols for /lib/ld-linux-armhf.so.3
Reading symbols from /lib/arm-linux-gnueabihf/libnss_files.so.2...Reading symbols from /usr/lib/debug/lib/arm-linux-gnueabihf/libnss_files-2.19.so...done.
done.
Loaded symbols for /lib/arm-linux-gnueabihf/libnss_files.so.2
0x763e1d14 in epoll_wait () at ../sysdeps/unix/syscall-template.S:81
81      ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) c
Continuing.

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x75358450 (LWP 4053)]
0x7633df70 in raise () from /lib/arm-linux-gnueabihf/libc.so.6
(gdb) bt
#0  0x7633df70 in raise () from /lib/arm-linux-gnueabihf/libc.so.6
#1  0x7633f324 in abort () from /lib/arm-linux-gnueabihf/libc.so.6
#2  0x7656eb5c in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#3  0x7656c9a0 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
#4  0x7656c9a0 in ?? () from /usr/lib/arm-linux-gnueabihf/libstdc++.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) c
Continuing.
[Thread 0x762ac000 (LWP 4050) exited]
[Thread 0x75b58450 (LWP 4052) exited]
[Thread 0x749ff450 (LWP 4054) exited]

Program terminated with signal SIGABRT, Aborted.
The program no longer exists.
(gdb)

我使用的守护程序代码:

// Daemonize
LOG_INFO( *logger ) << "Daemonizing.";

// Sig stuff
pid_t pid, sid;

// Start the forky pig
if( (pid = fork())<0 )
{
    LOG_ERROR( *logger ) << "Error forking: " << strerror( errno );
    return( EXIT_FAILURE );
}

// The parent can go home
if( pid>0 )
    return( EXIT_SUCCESS );

// Make ourselves emancipate
if( (sid = setsid())<0 )
{
    LOG_ERROR( *logger ) << "setsid error: " << strerror( errno );
    return( EXIT_FAILURE );
}

// Ignore sigpipes
signal( SIGPIPE, SIG_IGN );

// Close the file descriptors to detach
close( STDIN_FILENO );
close( STDOUT_FILENO );
close( STDERR_FILENO );

如果程序在没有被守护程序的情况下可以运行,而在它存在时崩溃,那么它的运行方式显然会有所不同。所以我的问题真的是,我在哪里可以找到这个特定的故障点?

在 64 位 Intel Arch 处理器上出现同样的错误:

Program received signal SIGABRT, Aborted.
[Switching to Thread 0x7f80777b8700 (LWP 10314)]
0x00007f807baa7297 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
55      ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007f807baa7297 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:55
#1  0x00007f807baa862a in __GI_abort () at abort.c:89
#2  0x00007f807c5a700d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libstdc++.so.6
#3  0x00007f807c5a4e96 in ?? () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libstdc++.so.6
#4  0x00007f807c5a4ee1 in std::terminate() () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libstdc++.so.6
#5  0x00007f807c600c21 in ?? () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.3/libstdc++.so.6
#6  0x00007f807be16324 in start_thread (arg=0x7f80777b8700) at pthread_create.c:333
#7  0x00007f807bb5bf6d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

【问题讨论】:

  • 您没有显示足够的信息来诊断问题。请尝试使用MCVE 重现您的症状,如果这不能帮助您识别问题,请返回此处并发布最小程序并再次解释问题。

标签: c++ linux gdb daemon


【解决方案1】:

在交互式环境中运行进程或作为守护进程运行进程是不同的。当您从命令行运行一个进程时,该进程将继承交互式环境中的所有资源,例如在环境 PATH 变量中定义的路径,甚至是工作目录,即在交互式环境中,实际目录来自哪里过程开始。

在不了解您的系统或环境的情况下,经常犯的错误之一是尝试启动后台进程、守护进程,例如从 crontab 中,但忘记提供进程运行所需的信息。例如,当一个进程作为守护进程运行时,在不知道您的工作流程情况的情况下,有必要为该进程提供环境,尤其是工作目录。例如,我使用 "chdir("/");" 来执行此操作,因此分叉的孩子会知道他在哪个工作目录上处于活动状态。

根据你的其他资源,你应该给守护进程所有信息,它需要完成它的工作,例如。如果它启动了某个进程,例如进程的 PATH 等等。

问候

【讨论】:

  • 这是一个很好的答案,非常感谢您的回答。我有一个问题是无法提出好的问题,所以我感谢你抽出时间来写这篇文章。
【解决方案2】:

原来是日志文件崩溃。我没有看到 throw 错误,因为错误与日志系统本身有关。由于与标准输出的所有联系都被切断,因此没有显示任何内容。 Boost.Log 正是这篇文章中的问题:

Boost Log causes crash when trying first log statement (when not Administrator)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-12
    • 2012-10-26
    • 1970-01-01
    • 2012-09-26
    • 2017-10-26
    • 2022-12-12
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多