LeakSanitizer 在 Ubuntu 18.04 中不能在 gdb 下工作?
LeakSanitizer not working under gdb in Ubuntu 18.04?
我最近将我的 Linux 开发 VM 从 Ubuntu 16.04 升级到 18.04,并注意到一件事发生了变化。这是在 x86-64 上。在 16.04 中,我一直有这样的工作流程,我在其中构建我正在使用 gcc(5.4,16.04 中的库存版本)和 -fsanitize=address
和 -O0 -g
的项目,然后 运行 通过 gdb 的可执行文件(7.11.1,也是 Ubuntu 附带的版本)。这工作正常,最后,如果检测到内存泄漏,LeakSanitizer 会生成泄漏报告。
在 18.04 中,这似乎不再有效; LeakSanitizer 在 ptrace 下抱怨 运行ning:
==5820==LeakSanitizer has encountered a fatal error.
==5820==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
==5820==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
然后程序崩溃:
Thread 1 "spyglass" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
我不确定是什么导致了新行为。在 18.04 上,我使用默认的 gcc (7.3.0) 进行构建,使用 -fsanitize=address -O0 -g
并使用默认的 gdb (8.1.0) 进行调试。可以以某种方式重新启用旧行为吗?或者我是否需要更改我的工作流程并在终止它以获得泄漏报告之前与程序分离?
LeakSanitizer 在内部使用 ptrace,可能会挂起所有线程,以便它可以扫描泄漏而不会误报(请参阅 issue 9)。只有一个应用程序可以使用 ptrace,因此如果您 运行 您的应用程序在 gdb 或 strace 下,那么 LeakSanitizer 将无法通过 ptrace 附加。
如果您对泄漏调试不感兴趣,请将其禁用:
export ASAN_OPTIONS=detect_leaks=0
如果您确实想要启用泄漏调试,则必须在 LeakSanitizer 开始扫描之前分离调试器。为了能够在不久之后附加调试器,请睡一会儿(例如,10 秒):
export ASAN_OPTIONS=sleep_before_dying=10
./program
然后在另一个 shell 中,再次附加到应用程序:
gdb -q -p $(pidof program)
有关上述(和其他)选项的更多说明,请参阅 https://github.com/google/sanitizers/wiki/AddressSanitizerFlags。
我最近将我的 Linux 开发 VM 从 Ubuntu 16.04 升级到 18.04,并注意到一件事发生了变化。这是在 x86-64 上。在 16.04 中,我一直有这样的工作流程,我在其中构建我正在使用 gcc(5.4,16.04 中的库存版本)和 -fsanitize=address
和 -O0 -g
的项目,然后 运行 通过 gdb 的可执行文件(7.11.1,也是 Ubuntu 附带的版本)。这工作正常,最后,如果检测到内存泄漏,LeakSanitizer 会生成泄漏报告。
在 18.04 中,这似乎不再有效; LeakSanitizer 在 ptrace 下抱怨 运行ning:
==5820==LeakSanitizer has encountered a fatal error.
==5820==HINT: For debugging, try setting environment variable LSAN_OPTIONS=verbosity=1:log_threads=1
==5820==HINT: LeakSanitizer does not work under ptrace (strace, gdb, etc)
然后程序崩溃:
Thread 1 "spyglass" received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
我不确定是什么导致了新行为。在 18.04 上,我使用默认的 gcc (7.3.0) 进行构建,使用 -fsanitize=address -O0 -g
并使用默认的 gdb (8.1.0) 进行调试。可以以某种方式重新启用旧行为吗?或者我是否需要更改我的工作流程并在终止它以获得泄漏报告之前与程序分离?
LeakSanitizer 在内部使用 ptrace,可能会挂起所有线程,以便它可以扫描泄漏而不会误报(请参阅 issue 9)。只有一个应用程序可以使用 ptrace,因此如果您 运行 您的应用程序在 gdb 或 strace 下,那么 LeakSanitizer 将无法通过 ptrace 附加。
如果您对泄漏调试不感兴趣,请将其禁用:
export ASAN_OPTIONS=detect_leaks=0
如果您确实想要启用泄漏调试,则必须在 LeakSanitizer 开始扫描之前分离调试器。为了能够在不久之后附加调试器,请睡一会儿(例如,10 秒):
export ASAN_OPTIONS=sleep_before_dying=10
./program
然后在另一个 shell 中,再次附加到应用程序:
gdb -q -p $(pidof program)
有关上述(和其他)选项的更多说明,请参阅 https://github.com/google/sanitizers/wiki/AddressSanitizerFlags。