- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我正在 linux 上开发一个应用程序,我想在其中以特定频率回溯所有正在运行的线程。所以我的用户定义的信号处理程序 SIGUSR1(对于所有线程)调用 backtrace()。
我的信号处理程序发生崩溃(SIGSEGV),它源自 backtrace() 调用。我已将正确的参数传递给大多数网站上指定的函数。 http://linux.die.net/man/3/backtrace .
在这种情况下,什么会导致 backtrace() 崩溃?
要添加更多详细信息:
让我得出崩溃发生在回溯内部的结论是下面的第 14 帧。 onMySignal 是信号处理程序 SIGUSR1,它调用回溯。
onMySignal 的示例代码是(从 backtrace 的 linux 文档中复制的)
pthread_mutex_lock( &sig_mutex );
int j, nptrs;
#define SIZE 100
void *buffer[100] = {NULL};//or void *buffer[100];
char **strings;
nptrs = backtrace(buffer, SIZE);
pthread_mutex_unlock( &sig_mutex );
(gdb) where
#0 0x00000037bac0e9dd in raise () from
#1 0x00002aaabda936b2 in skgesigOSCrash () from
#2 0x00002aaabdd31705 in kpeDbgSignalHandler ()
#3 0x00002aaabda938c2 in skgesig_sigactionHandler ()
#4 <signal handler called>
#5 0x00000037ba030265 in raise () from
#6 0x00000037ba031d10 in abort () from
#7 0x00002b6cef82efd7 in os::abort(bool) () from
#8 0x00002b6cef98205d in VMError::report_and_die() ()
#9 0x00002b6cef835655 in JVM_handle_linux_signal ()
#10 0x00002b6cef831bae in signalHandler(int, siginfo*, void*) ()
#11 <signal handler called>
#12 0x00000037be407638 in ?? ()
#13 0x00000037be4088bb in _Unwind_Backtrace ()
#14 0x00000037ba0e5fa8 in backtrace ()
#15 0x00002aaaaae3875f in onMySignal (signum=10,info=0x4088ec80, context=0x4088eb50)
#16 <signal handler called>
#17 0x00002aaab4aa8acb in mxSession::setPartition(int)
#18 0x0000000000000001 in ?? ()
#19 0x0000000000000000 in ?? ()
(gdb)
希望这将使问题更清楚..
@janneb为了更好的同步,我在互斥锁中编写了信号处理程序实现。
@janneb我没有在指定 API backtrace_symbols/backtrace 的文档中找到是否为 async_signal_safe。以及它们是否应该在信号处理程序中使用。
我仍然从我的信号处理程序中删除了 backtrace_symbols 并且没有在任何地方使用它..但是我在 backtrace() 中崩溃的实际问题仍然存在。不知道为什么它会崩溃..
(gdb) where
#0 0x00000037bac0e9dd in raise () from
#1 0x00002aaab98a36b2 in skgesigOSCrash () from
#2 0x00002aaab9b41705 in kpeDbgSignalHandler () from
#3 0x00002aaab98a38c2 in skgesig_sigactionHandler () from
#4 <signal handler called>
#5 0x00000037ba030265 in raise () from
#6 0x00000037ba031d10 in abort () from
#7 0x00002ac003803fd7 in os::abort(bool) () from
#8 0x00002ac00395705d in VMError::report_and_die() () from
#9 0x00002ac00380a655 in JVM_handle_linux_signal () from
#10 0x00002ac003806bae in signalHandler(int, siginfo*, void*) () from
#11 <signal handler called>
#12 0x00000037be407638 in ?? () from libgcc_s.so.1
#13 0x00000037be4088bb in _Unwind_Backtrace () from libgcc_s.so.1
#14 0x00000037ba0e5fa8 in backtrace () from libc.so.6
#15 0x00002aaaaae3875f in onMyBacktrace (signum=10, info=0x415d0eb0, context=0x415d0d80)
#16 <signal handler called>
#17 0x00000037ba071fa8 in _int_free () from libc.so.6
#18 0x00000000000007e0 in ?? ()
#19 0x000000005aab01a0 in ?? ()
#20 0x000000000000006f in ?? ()
#21 0x00000037ba075292 in realloc () from libc.so.6
#22 0x00002aaab6248c4e in Memory::reallocMemory(void*, unsigned long, char const*, int) ()
在执行 realloc 时发生崩溃,其中一个地址类似于 0x00000000000007e0(看起来无效)..
最佳答案
documentation for signal handling定义了从信号处理程序调用的安全函数列表,您不得使用任何其他函数,包括 backtrace
。 (在该文档中搜索 async-signal-safe
)
您可以做的是写入
您之前设置的管道,并让一个线程等待该管道,然后执行回溯。
编辑:
好的,backtrace
函数返回当前线程的堆栈,所以不能从另一个线程使用,所以我使用单独线程进行回溯的想法行不通。
因此:您可以从信号处理程序中尝试 backtrace_symbols_fd
。
作为替代方案,您可以使用 gdb
获取回溯,而无需在您的程序中添加代码 - 而且 gdb
可以轻松处理多个线程。
运行 gdb 并取回跟踪的 Shell 脚本:
#!/bin/bash
PID="$1"
[ -d "/proc/$PID" ] || PID=$(pgrep $1)
[ -d "/proc/$PID" ] || { echo "Can't find process: $PID" >&2 ; exit 1 ; }
[ -d "$TMPDIR" ] || TMPDIR=/tmp
BATCH=$(mktemp $TMPDIR/pstack.gdb.XXXXXXXXXXXXX)
echo "thread apply all bt" >"$BATCH"
echo "quit" >>"$BATCH"
gdb "/proc/$PID/exe" "$PID" -batch -x "$BATCH" </dev/null
rm "$BATCH"
关于linux - 是什么让 64 位 Linux 上的 backtrace() 崩溃(SIGSEGV),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6371028/
好的,我已经使用 Linux Dwarf ldw 库将 backtrace_symbols 输出转换为源代码和行号,但遇到了障碍。 backtrace_symbols 给出内存中的偏移量,在用作 Dw
我正在尝试让 Emacs 24.3.1 在出现错误时打开 *Backtrace* 缓冲区,但我尝试的任何方法似乎都不起作用。这包括评估 (setq debug-on-error t)、运行 toggl
当我的应用崩溃时,我使用 backtrace 和 backtrace_symbols 来收集调用堆栈。 void InstallSignalHandler(void) { signal(SIG
我在一个自定义的 malloc() 中使用了 backtrace() 函数,像这样: void *malloc(size_t size) {printf("my malloc!\n")
我正在查看 gdb 中的回溯,它看起来非常困惑,因为对标准库和 boost 进行了所有调用。例如。我在调用堆栈上看到 boost::bind 和 std::allocator,以及对标准库或 Boos
我的 iPhone 应用程序最近被 App Store 拒绝,“因为它在启动时崩溃”。但是,我无法重现此崩溃。该应用程序在模拟器和具有相同硬件和软件的设备上都能完美运行,Apple 对其进行了测试(运
在创建用于单元测试的辅助方法时,失败的控制台输出仅指示实际发生断言的行。 # Just an example method. def test_equal(a, b) assert_equal a
我按照 this post 中的描述打印了当前堆栈指针 void myFunc1(void) { char *p; char b=0x11; p = &b; print
我有一个继承自 Base 的 Derived 类,但我的其中一个函数发生了崩溃。我打开 gdb 试图弄清楚发生了什么,并试图打印出回溯。然而,当我 100% 知道路径是:Derived::func -
我有多个项目。每个项目创建自己的 so 文件。出于某种原因,回溯不会打印函数,因此会在崩溃时生成文件。 我用 -rdynamic 编译。例如:-std=c++14 -pthread -pedantic
我试图准确捕获哪个方法,或者至少是哪个类使我的代码崩溃 回溯在收到 SIGSEGV 信号后返回的消息。是不是因为崩溃的方法在另一个线程上执行,因此回溯无法这样做(请参阅我的日志的第一行 - 进程 ID
我的日志记录代码使用 backtrace() 的返回值确定当前堆栈深度(用于 pretty-print 目的),但我可以从分析中看出这是一个非常昂贵的调用。 我不认为有更便宜的方法来做到这一点?请注意
我正在开发通过 NDK 与 Android 配合使用的 native 应用程序。我需要调用backtrace()发生崩溃时的功能。问题是没有对于 NDK。 还有其他方法可以获取该回溯吗? 最佳答案 A
我有一个在 linux 64 位系统下运行的发行版服务器进程。它崩溃了并留下了一个核心转储文件。我使用 gdb 调试它是这样的: gdb svr 核心转储文件 并得到以下回溯: (gdb) where
在GDB,做backtrace full将以十进制打印所有局部变量及其值。 有没有办法以十六进制而不是十进制打印局部变量值? (我想要类似于 print/x myVar 的东西。) 最佳答案 您可能想
启用错误调试时,我遇到了 Backtrace 缓冲区中损坏文本的问题。像这样。 示例 它用日语说也许。但是,我无法理解该消息。有谁知道解决方法?我可以用英文显示消息。任何帮助,将不胜感激。提前致谢。
是否有任何 Raspberry Pi 优化/特定的 backtrace() 实现?我正在使用标准 backtrace() 代码,但期待 my_backtrace 函数的更详细输出。 void my_b
我正在运行此测试,因为我想查看程序的堆栈跟踪。下面是我的程序: public class NanoTime { public static void main (String[] args) {
在 Linux 下运行的 ARM 平台上创建回溯时,我遇到了奇怪的行为。有时回溯输出似乎已损坏,具体取决于故障之前执行的代码。 这是我的Crash.cpp代码: #include #include
Clang 编译器提供了许多有用的运行时检查,例如-fsanitize=unsigned-integer-overflow .当其中一项检查失败时,我可以打印回溯(例如使用 gdb)吗?目前我得到了问
我是一名优秀的程序员,十分优秀!