当我使用 -fsanitize=address 标志编译时调用虚函数导致崩溃

问题描述 投票:0回答:1
using namespace std;
class A {
    public:
        virtual void fun1()=0;
};
class B : public A {
    public:
        virtual void fun1();
};
void B::fun1() {
    cout << " In B::fun1 function\n" << endl; 
}
class C {
    public:
        A *pobj;
        void Reset(A *pobj);
        void fun2();
};
void C::fun2() {
    pobj->fun1();
}
void C::Reset(A* p_obj) {
     pobj = p_obj;
}
class D {
    public:
        C cobj;
        bool initialized;
        void Initialize(A *pAobj);
};
void D::Initialize(A *pAobj) {      // casting
    if(initialized == false) {
        initialized = true;
        cobj.Reset(pAobj);
    }
    cobj.fun2();
}

class E {
    public:
        E();
        ~E();
        void fun4();
        void fun5();
        D *p_Dobj;
};
E::E()
    : p_Dobj(new D){
}
E::~E() {
    if(p_Dobj != NULL) {
        delete p_Dobj;
    }
}
void E::fun4() {
    B Bobj;    // Created Local Object which may causing issue.
    p_Dobj->Initialize(&Bobj);
}
void E::fun5() {
    fun4();
    fun4();
}
int main() {
    E Eobj;
    Eobj.fun5();
    return 0;
}
When i am compiling the above code like,
$clang++ Demo.cpp
then is is properly working,
$./a.out
Output:

在 B::fun1 函数中

在 B::fun1 函数中

but when i compile with -fsanitize=address flag like,
$clang++ -fsanitize=address Demo.cpp
Output:

在 B::fun1 函数中

==32155==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f49b5900060 at pc    0x565479ba8963 bp 0x7fff9ca67730 sp 0x7fff9ca67728

在 0x7f49b5900060 线程 T0 读取大小 8 #0 0x565479ba8962 (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4962) #1 0x565479ba8aae (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4aae) #2 0x565479ba8cab (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4cab) #3 0x565479ba8d21 (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4d21) #4 0x565479ba8e04 (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4e04) #5 0x7f49b7f8f082 (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee) #6 0x565479ad337d (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0x1f37d)

地址 0x7f49b5900060 位于帧中偏移量 32 处的线程 T0 堆栈中 #0 0x565479ba8bbf (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4bbf)

此框架有 1 个对象: [32, 40) 'Bobj'(第 68 行)<== Memory access at offset 32 is inside this variable HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork (longjmp and C++ exceptions are supported) SUMMARY: AddressSanitizer: stack-use-after-return (/home/excellarate/Desktop/All Tasks/Wasm/a.out+0xf4962) Shadow bytes around the buggy address: 0x7f49b58ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b58ffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b58ffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b58fff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b58fff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x7f49b5900000: f1 f1 f1 f1 00 f3 f3 f3 f5 f5 f5 f5[f5]f5 f5 f5 0x7f49b5900080: f1 f1 f1 f1 00 f3 f3 f3 00 00 00 00 00 00 00 00 0x7f49b5900100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b5900180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b5900200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x7f49b5900280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 影子字节图例(一个影子字节代表8个应用字节):

when it is calling virtual function (fun1) then there is crash occur can you explain why it is happening?
Share documentation related to this issue if possible

Thanks in advance!

Understanding the virtual function issues
c++ clang clang++ virtual-functions address-sanitizer
1个回答
0
投票

我不认为这真的与虚函数有任何关系。这是一个简单的终身问题,您自己的评论指出了这一点。在对

fun4()
的第一次调用中,您使用指向本地对象
p_Dobj->Initialize
的指针调用
Bobj
,这导致
p_Dobj->cobj.pobj
指向该对象,并且
p_Dobj->initialized
设置为
true
。当
fun4()
返回时,该对象的生命周期结束。当您第二次调用
fun4()
时,
p_Dobj->initialized
true
所以
p_Dobj->cobj.pobj
被单独留下,并且在对
p_Dobj->cobj.fun2()
的调用中被取消引用。因此,您正在取消引用指向生命周期已结束且行为未定义的对象的指针。

Bonus bug:在

D::Initialize
中,具有讽刺意味的是,成员
initialized
在没有被初始化的情况下读取。

© www.soinside.com 2019 - 2024. All rights reserved.