刚刚遇到了这个非常奇怪的错误。在现有包含类中添加新的
shared_ptr
实例变量后,由于内存错误,我遇到了崩溃。
当我在 Xcode 中使用 AddressSanitizer 运行时,当实例化包含类的对象时(即在其 CTOR 处),它会报告新 iVar 上的堆缓冲区溢出。
我无法在简单的系统中复制它,并且这是专有代码(所以我无法在这里完整地展示它)。 但是,我可以简单地通过声明一个简单类型(int)的新的shared_ptr实例变量来触发错误。
我的课基本上都是
// MyContainingClass.h
#include <memory>
// Forward
class HelperObject;
class MyContainingClass {
public:
MyContainingClass();
...
private:
std::shared_ptr<HelperObject> _helperObject;
};
//MyContainingClass.cpp
#include "HelperObject.h"
...
MyContainingClass::MyContainingClass() {
_helperObject = std::make_shared<HelperObject>();
}
...
运行良好。但是当我尝试这个时(添加一行:新的 iVar)
// MyContainingClass.h
#include <memory>
// Forwards
class HelperObject;
class DifferentHelperObject;
class MyContainingClass {
public:
MyContainingClass();
...
private:
std::shared_ptr<HelperObject> _helperObject;
std::shared_ptr<DifferentHelperObject> _differentHelperObject; // <- NEW LINE
};
我在 MyContainingClass CTOR 处遇到堆缓冲区溢出,即使没有尝试分配 DifferentHelperObject。。 (如果我do在CTOR中创建智能指针,我会得到同样的错误。)
如果我更改声明顺序,AddressSanitizer 会在
HelperObject
而不是 DifferentHelperObject
报告错误(即以第二个声明者为准)。
DifferentHelperObject 是一个相当简单的类型;它只包含简单的 POD 成员和方法(没有指针、数组、智能指针等),所以我尝试用一些真正简单的东西替换它:a
std::shared_ptr<int>
:
std::shared_ptr<HelperObject> _helperObject;
std::shared_ptr<int> _anInt; //Adding just this line to otherwise working code causes a crash
我现在在shared_ptr上发现堆缓冲区溢出
_anInt.
这就是最后一种情况的 AddressSanitizer 输出:
SUMMARY: AddressSanitizer: heap-buffer-overflow (/private/var/containers/Bundle/Application/XXXXXXX/MyApp.app/MyApp:arm64+0x10aa0e120) in std::__1::shared_ptr<int>::shared_ptr()+0x4c
Shadow bytes around the buggy address:
0x0002a56ea260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0002a56ea270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0002a56ea280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0002a56ea290: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0002a56ea2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0002a56ea2b0: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
0x0002a56ea2c0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0002a56ea2d0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0002a56ea2e0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0002a56ea2f0: fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0002a56ea300: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
AddressSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
(lldb) thread info -s
thread #1: tid = 0xb9794, 0x000000012446b328 libclang_rt.asan_ios_dynamic.dylib`__asan::AsanDie(), queue = 'com.apple.main-thread', stop reason = Heap buffer overflow
{
"access_size": 8,
"access_type": 1,
"address": 5023012304,
"description": "heap-buffer-overflow",
"instrumentation_class": "AddressSanitizer",
"pc": 4543308068,
"stop_type": "fatal_error"
}
(lldb)
调用堆栈如下所示:
Thread 1 Queue : com.apple.main-thread (serial)
#0 0x000000012446b328 in __asan::AsanDie() ()
#1 0x000000012448096c in __sanitizer::Die() ()
#2 0x000000012446890c in __asan::ScopedInErrorReport::~ScopedInErrorReport() ()
#3 0x000000012446813c in __asan::ReportGenericError(unsigned long, unsigned long, unsigned long, unsigned long, bool, unsigned long, unsigned int, bool) ()
#4 0x000000012446943c in __asan_report_store8 ()
#5 0x000000010ecd6124 in std::__1::shared_ptr<int>::shared_ptr() at /Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/memory:2983
#6 0x000000010ecd119c in std::__1::shared_ptr<int>::shared_ptr() at /Applications/Xcode_13.2.1.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/usr/include/c++/v1/memory:2985
#7 0x000000010ecd0f08 in MyContainingClass::MyContainingClass() at /Users/xxx/MyContainingClass.cpp:22
#8 0x000000010ecd1870 in MyContainingClass::MyContainingClass() at /Users/xxx/MyContainingClass.cpp:22
我一直在尝试理解 AddressSanitizer 的输出;影子内存地址似乎没有正确映射到实际程序内存(乘以 8,仍然存在偏移量。因此,任何帮助理解上面的 AddressSanitizer 输出如何可以为我指出实际问题(或建议实际问题可能是什么)是)将不胜感激。
非常奇怪的错误。在现有的包含类中添加新的shared_ptr实例变量后,由于内存错误,我遇到了崩溃。
我无法在简单的系统中复制这个
这通常是重建一些代码的结果,但不是全部,其中包括
MyContainingClass.h
。
尝试“从头开始”构建。崩溃和 AddressSanitizer 问题很可能都会消失。
我也有同样的问题。就我而言,正如@user17732522提到的,这是一种症状,而不是问题本身。
我有静态库和与该库链接的可执行文件。库和可执行文件都包含相同的头文件:
class Config
{
public:
bool foo;
bool bar;
#if defined(DEFINITION)
bool baz;
#endif
};
DEFINITION
在库中定义,但未在可执行文件中定义
所以下面的课程:
class Class {
// ...
private:
Config config_;
std::shared_ptr<int> obj1_;
std::shared_ptr<HelperObject> obj2_;
}
产生了相同的 ASan 错误:
=================================================================
==7202==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60c000000180 at pc 0x000000c33b5d bp 0x7ffc29bc1da0 sp 0x7ffc29bc1d98
WRITE of size 8 at 0x60c000000180 thread T0
#0 0xc33b5c in std::__1::shared_ptr<HelperObject>::shared_ptr() /usr/local/include/c++/v1/memory:4047:7