gpt4 book ai didi

c++ - 读取指向函数中的变量时出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 03:14:51 25 4
gpt4 key购买 nike

我有以下几段代码:(注意:由于我无法共享数据,代码已简化并更改了很多)

练习.cpp

#include "some_api.h"

extern "C" int extension_init(func_t*, VExtension*);

int main(int argc, char** argv)
{
VExtension ve;
extension_init(&func, &ve);
return 0;
}

some_api.h

bool func(int const& a, void* const& b, VExtension* const& v)
{
std::cout << a << b << std::endl;
}

api.h

typedef int (func_t)(int c, void* p, VExtension* v)

文件.cpp

#include "api.h" // this is included implicitly

extern "C" int extension_init(func_t* F, VExtension* v)
{
intptr_t ver = 7;
F(1, (void*)ver, v);
}

所以,当F被调用时,func是从some_api.h调用的,但是Seg Fault出现在尝试输出值 ab。静态分析器给出以下错误信息:

ASAN:DEADLYSIGNAL
=================================================================
==15==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000001 (pc 0x55d6dbe48ca2 bp 0x7fff79dbf320 sp 0x7fff79dbf300 T0)
==15==The signal is caused by a READ memory access.
==15==Hint: address points to the zero page.
#0 0x55d6dbe48ca1 in func(int const&, void* const&, VExtension* const&) some_api.h:279
#1 0x55d6dbefe697 in file.cpp:809
#2 0x55d6dbe5373a in main exercise.cpp:123
#3 0x7f9c65393b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#4 0x55d6dbd49839 in _start (//...)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: some_api.h:279 in func(int const&, void* const&, VExtension* const&)
==15==ABORTING

最佳答案

更正后的代码可以工作

如果 func_t 将使用与 func() 相同的签名来定义,那么一切都会很好,因为 b 的任意值永远不会被取消引用:

typedef bool (func_t)(int const& a, void* const& b, VExtension* const& v);

参见 demo .

但是你的代码不能,所以这里有些可疑

您的代码似乎可以编译,至少从您显示的运行时跟踪来看是这样。但是根据您发布的片段,代码根本不应该编译。因此,我怀疑您的不同 header 在不同的编译单元中使用来自 func_t 的不同定义,设法创建了一个危险的组合。如果是这种情况,您将处于未定义行为的世界中。

例如,返回类型 int 与返回类型 bool 不匹配。但更致命的是,在 func_t 中,参数是普通值,而在 func() 中,它们都是引用。因此,如果编译器被欺骗,func() 的调用者使用的调用约定将与 func() 使用的调用约定不兼容,从而导致无效的内存访问(最有可能——但这将取决于实现——生成的调用代码将发送值参数,但生成的接收代码将期望这些参数是指向值的指针并尝试访问指向的内存位置,这将是无效的) .

补充说明

现在,我不是语言律师,但看到一个使用 C 调用约定 (extern "C") 的函数,使用在C(即 bool 和引用)。

其他见解

查看 assembly code generated对于使用 func_t 的更正定义的一个编译器上的 extension_init:

lea rdx, [rsp+8]           ; load effective address of third paramvalue
lea rsi, [rsp+24] ; load effective address of second param value
mov QWORD PTR [rsp+24], 7 ; initialize value
lea rdi, [rsp+20] ; load effective address of first param value
mov DWORD PTR [rsp+20], 1 ; initilize value
call rax

如果using your original definition ,生成的代码看起来不同:

                ; the third value was left out by the global initializer
; but it was previously set with an LEA to load the effective
; address of the struct.
mov esi, 7 ; pass the second value
mov edi, 1 ; pass the first value
call rax

关于c++ - 读取指向函数中的变量时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52952476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com