- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在尝试找出在启用 Address Sanitizer (ASAN) 的情况下运行我的应用程序时看到的段错误的根本原因。当我附加 GDB 并调试应用程序时,我看到在方法的开头收到了段错误:
最少的代码:
int TimerScope::switchMode() {
doCapture(mode)
}
> int TimerScope::doCapture(Mode captureMode) { <---- segfault here
if(handle == -1)
return 0;
XLOG(TRACE, image(this));
..
}
请注意,我没有看到没有地址清理器的构建的问题。我已经看过这个问题的不同方面(比如寻找变量的垃圾地址,运行 valgrind/UBSAN 等)但没有任何运气。目前我正在查看汇编代码以查看是否有任何线索。使用 GDB,当我打印段错误的位置时,这就是我得到的:
(gdb) p $_siginfo._sifields._sigfault.si_addr
$5 = (void *) 0x7fe4d3908fb8
汇编代码如下所示,它在调用 TimerScope::doCapture
方法时执行一些逻辑:
0x7fe69595f65e <_ZN7ts9TimerScope9doCaptureENS_8ModeE> endbr64 │
│ 0x7fe69595f662 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+4> push %rbp │
│ 0x7fe69595f663 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+5> mov %rsp,%rbp │
│ 0x7fe69595f666 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+8> push %r15 │
│ 0x7fe69595f668 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+10> push %r14 │
│ 0x7fe69595f66a <_ZN7ts9TimerScope9doCaptureENS_8ModeE+12> push %r13 │
│ 0x7fe69595f66c <_ZN7ts9TimerScope9doCaptureENS_8ModeE+14> push %r12 │
│ 0x7fe69595f66e <_ZN7ts9TimerScope9doCaptureENS_8ModeE+16> push %rbx │
│ 0x7fe69595f66f <_ZN7ts9TimerScope9doCaptureENS_8ModeE+17> sub $0x1000,%rsp │
│ 0x7fe69595f676 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+24> orq $0x0,(%rsp) │
│ 0x7fe69595f67b <_ZN7ts9TimerScope9doCaptureENS_8ModeE+29> sub $0x1a8,%rsp │
│ > 0x7fe69595f682 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+36> mov %rdi,-0x1198(%rbp) │
│ 0x7fe69595f689 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+43> mov %esi,%eax │
│ 0x7fe69595f68b <_ZN7ts9TimerScope9doCaptureENS_8ModeE+45> mov %al,-0x119c(%rbp) │
│ 0x7fe69595f691 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+51> lea -0x1170(%rbp),%rax │
│ 0x7fe69595f698 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+58> mov %rax,-0x11a8(%rbp) │
│ 0x7fe69595f69f <_ZN7ts9TimerScope9doCaptureENS_8ModeE+65> mov %rax,-0x11c0(%rbp) │
│ 0x7fe69595f6a6 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+72> mov 0x7b92943(%rip),%rax # 0x7fe69d4f1ff0 │
│ 0x7fe69595f6ad <_ZN7ts9TimerScope9doCaptureENS_8ModeE+79> cmpl $0x0,(%rax) │
│ 0x7fe69595f6b0 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+82> je 0x7fe69595f6c8 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+106> │
│ 0x7fe69595f6b2 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+84> mov $0x1120,%edi │
│ 0x7fe69595f6b7 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+89> call 0x7fe6952d6510 <__asan_stack_malloc_7@plt> │
│ 0x7fe69595f6bc <_ZN7ts9TimerScope9doCaptureENS_8ModeE+94> test %rax,%rax │
│ 0x7fe69595f6bf <_ZN7ts9TimerScope9doCaptureENS_8ModeE+97> je 0x7fe69595f6c8 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+106> │
│ 0x7fe69595f6c1 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+99> mov %rax,-0x11a8(%rbp) │
│ 0x7fe69595f6c8 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+106> mov -0x11a8(%rbp),%rbx │
│ 0x7fe69595f6cf <_ZN7ts9TimerScope9doCaptureENS_8ModeE+113> lea 0x1140(%rbx),%rax
特别是,以下是出现段错误的行:
0x7fe69595f682 <_ZN7ts9TimerScope9doCaptureENS_8ModeE+36> mov %rdi,-0x1198(%rbp)
这里执行的逻辑是什么?我可以看到寄存器rbp
的值是0x7fe4d390a150
,故障地址0x7fe4d3908fb8
可以通过减去0x1198
得到来自 0x7fe4d390a150
。为什么地址 0x7fe4d3908fb8
会导致段错误?
框架信息如下:
(gdb) info frame
Stack level 0, frame at 0x7fe4d390a160:
rip = 0x7fe69595f682 in ts::TimerScope::doCapture (/tsmgr/src/TimerScope.cpp:142);
saved rip = 0x7fe69595ec93
called by frame at 0x7fe4d390a540
source language c++.
Arglist at 0x7fe4d390a150, args: this=0x0, mode=ts::Mode::None
Locals at 0x7fe4d390a150, Previous frame's sp is 0x7fe4d390a160
Saved registers:
rbx at 0x7fe4d390a128, rbp at 0x7fe4d390a150, r12 at 0x7fe4d390a130, r13 at 0x7fe4d390a138, r14 at 0x7fe4d390a140, r15 at 0x7fe4d390a148, rip at 0x7fe4d390a158
另一件奇怪的事情是,如果我此时分离调试器,为段错误打印的错误消息显示不同的错误地址 (0x3e95c1f300086ab5):
*** Aborted at 1659061552 (Unix time, try 'date -d @1659061552') ***
*** Signal 11 (SIGSEGV) (0x3e95c1f300086ab5) received by PID 551605 (pthread TID 0x7fbe64166700) (linux TID 551964) (maybe from PID 551605, UID 1050001907) (code: -6), stack trace: ***
ASAN 也报告相同的地址:
==551605==ERROR: AddressSanitizer: SEGV on unknown address 0x3e95c1f300086ab5 (pc 0x7fbf388386c4 bp 0x7fbe64128100 sp 0x7fbe641260d8 T358)
==551605==The signal is caused by a WRITE memory access.
为什么 GDB 报告的故障地址与信号处理程序 ASAN 打印的地址不同?
在出现段错误的回溯中,this
和 mode
尚未在方法调用后设置(因此它们显示的值与第 1 帧中的值不同) :
#0 0x00007fe69595f682 in ts::TimerScope::doCapture(this=0x0, mode=ts::Mode::None)
at /tsmgr/src/TimerScope.cpp:142
#1 0x00007fe69595ec93 in ts::TimerScope::switchMode(this=0x612002750d40, mode=ts::Mode::Exclusive)
at /tsmgr/src/TimerScope.cpp:132
#2 0x00007fe6993b2c2b in ts::DataTimer::switchMode(this=0x6040021ac4e0, mode=ts::Mode::Exclusive)
at /tsmgr/src/DataTimer.hpp:84
#3 0x00007fe6993c47c6 in ts::DataTimerScope::switchMode(this=0x6030037d13d0, mode=ts::Mode::Exclusive)
at /tsmgr/src/DataTimerScope.cpp:49
#4 0x00007fe698e0a02a in ts::DataEntry::changeTimerMode (this=0x7fe29ba72700, mode=ts::Mode::Exclusive)
我正在使用支持 libasan6 的 gcc/g++-10 来构建应用程序,并在 ubuntu 20.04 环境中运行它。
能够仅提供代码片段,因为还有许多其他逻辑很难以合理的方式呈现。关于如何进一步处理该问题的任何指示都会有所帮助。当需要更多信息时,会不断更新问题。
编辑 #1:在段错误点,帧 0 中的堆栈指针与堆栈底部(帧 76)中的堆栈指针之间的差异为 199568 字节。栈空间大小设置为8M(默认)
对于故障地址:
(gdb) p $_siginfo._sifields._sigfault.si_addr
$2 = (void *) 0x7f442a630c68
并且 rbp
指向 0x7f442a632150
使用 info proc mappings
,我看到以下地址匹配:
0x7f4429e71000 0x7f442a631000 0x7c0000 0x0
0x7f442a631000 0x7f442a671000 0x40000 0x0
最佳答案
我还在多线程应用程序中使用 AddressSanitizer 构建。我还遇到过一些情况,其中 AddressSanitizer 构建在代码中创建了段错误,但代码却很好。所以在我的例子中,段错误的根源是特定线程上的小堆栈大小。
AddressSanitizer 构建有时需要多达 3 倍的堆栈内存。
以下是 clang 编译器的所有限制:https://clang.llvm.org/docs/AddressSanitizer.html#limitations
关于c++ - 方法最开始的段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73578021/
我已经使用 vue-cli 两个星期了,直到今天一切正常。我在本地建立这个项目。 https://drive.google.com/open?id=0BwGw1zyyKjW7S3RYWXRaX24tQ
您好,我正在尝试使用 python 库 pytesseract 从图像中提取文本。请找到代码: from PIL import Image from pytesseract import image_
我的错误 /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches non-TLS reference
我已经训练了一个模型,我正在尝试使用 predict函数但它返回以下错误。 Error in contrasts<-(*tmp*, value = contr.funs[1 + isOF[nn]])
根据Microsoft DataConnectors的信息我想通过 this ODBC driver 创建一个从 PowerBi 到 PostgreSQL 的连接器使用直接查询。我重用了 Micros
我已经为 SoundManagement 创建了一个包,其中有一个扩展 MediaPlayer 的类。我希望全局控制这个变量。这是我的代码: package soundmanagement; impo
我在Heroku上部署了一个应用程序。我正在使用免费服务。 我经常收到以下错误消息。 PG::Error: ERROR: out of memory 如果刷新浏览器,就可以了。但是随后,它又随机发生
我正在运行 LAMP 服务器,这个 .htaccess 给我一个 500 错误。其作用是过滤关键字并重定向到相应的域名。 Options +FollowSymLinks RewriteEngine
我有两个驱动器 A 和 B。使用 python 脚本,我在“A”驱动器中创建一些文件,并运行 powerscript,该脚本以 1 秒的间隔将驱动器 A 中的所有文件复制到驱动器 B。 我在 powe
下面的函数一直返回这个错误信息。我认为可能是 double_precision 字段类型导致了这种情况,我尝试使用 CAST,但要么不是这样,要么我没有做对...帮助? 这是错误: ERROR: i
这个问题已经有答案了: Syntax error due to using a reserved word as a table or column name in MySQL (1 个回答) 已关闭
我的数据库有这个小问题。 我创建了一个表“articoli”,其中包含商品的品牌、型号和价格。 每篇文章都由一个 id (ID_ARTICOLO)` 定义,它是一个自动递增字段。 好吧,现在当我尝试插
我是新来的。我目前正在 DeVry 在线学习中级 C++ 编程。我们正在使用 C++ Primer Plus 这本书,到目前为止我一直做得很好。我的老师最近向我们扔了一个曲线球。我目前的任务是这样的:
这个问题在这里已经有了答案: What is an undefined reference/unresolved external symbol error and how do I fix it?
我的网站中有一段代码有问题;此错误仅发生在 Internet Explorer 7 中。 我没有在这里发布我所有的 HTML/CSS 标记,而是发布了网站的一个版本 here . 如您所见,我在列中有
如果尝试在 USB 设备上构建 node.js 应用程序时在我的树莓派上使用 npm 时遇到一些问题。 package.json 看起来像这样: { "name" : "node-todo",
在 Python 中,您有 None单例,在某些情况下表现得很奇怪: >>> a = None >>> type(a) >>> isinstance(a,None) Traceback (most
这是我的 build.gradle (Module:app) 文件: apply plugin: 'com.android.application' android { compileSdkV
我是 android 的新手,我的项目刚才编译和运行正常,但在我尝试实现抽屉导航后,它给了我这个错误 FAILURE: Build failed with an exception. What wen
谁能解释一下?我想我正在做一些非常愚蠢的事情,并且急切地等待着启蒙。 我得到这个输出: phpversion() == 7.2.25-1+0~20191128.32+debian8~1.gbp108
我是一名优秀的程序员,十分优秀!