CppUTest Mock返回指针地址截断致段错误的原因排查
CppUTest Mock返回指针被截断为32位引发段错误的排查方向
问题描述
使用CppUTest Mock时出现段错误:Mock返回结构体指针时,Mock内部打印的是完整的64位地址(例如0x7ffd59372178),但调用Mock的函数中接收到的指针地址被截断为32位(例如0x59372178),进而因访问错误内存触发段错误。已排除结构体定义不一致、C/C++交互问题,怀疑是构建链问题,求可能的原因。
测试代码
test.cpp
#include "CppUTest/TestHarness.h" #include "CppUTestExt/MockSupport.h" #include "CppUTest/CommandLineTestRunner.h" extern "C" { #include "includes.h" #include <stdio.h> DivStruct_t* GetDivPtr() { void* retVal = mock().actualCall("GetDivPtr").returnPointerValue(); printf("fake div in mock %p \n", retVal); return (DivStruct_t*)retVal; } } TEST_GROUP( mockTest ) { void setup() { // Initialize before each test } void teardown() { // Deinitialize after each test mock().clear(); } }; TEST ( mockTest, passingPointer ) { DivStruct_t fakeDiv; fakeDiv.f1 = 8.0; fakeDiv.f2 = 6.0; printf("fake div addr %p \n", (void*)&fakeDiv); mock().expectOneCall("GetDivPtr").andReturnValue(&fakeDiv); Cfunction(); mock().checkExpectations(); }
function.c
#include "includes.h" void Cfunction() { DivStruct_t* div = GetDivPtr(); // seg fault happens here printf("div addr %p \n", (void*)&div); float f1Val = div->f1; return; }
includes.h
typedef struct { float f1; float f2; } DivStruct_t; DivStruct_t* GetDivPtr(); void Cfunction();
main.cpp
#include "CppUTest/CommandLineTestRunner.h" int main( int ac, char ** av ) { return CommandLineTestRunner::RunAllTests( ac, av ); }
可能的构建链原因
- 编译位数不一致:部分文件(如
test.cpp)以64位模式编译(默认-m64),而业务代码function.c以32位模式编译(指定-m32)。32位环境下指针为4字节,64位为8字节,跨位数调用时返回的64位指针会被截断为32位。 - 链接库位数不匹配:CppUTest库本身是32位编译产物,但测试程序以64位编译,或者反之。链接阶段未检测到位数差异,导致指针传递时高位丢失。
- 编译器ABI差异:不同编译器(如GCC与Clang)或同一编译器的不同版本间ABI不兼容,导致指针返回值的处理逻辑出错,造成地址截断。
- 隐式函数声明问题:若某文件未正确包含
includes.h,可能触发GetDivPtr()的隐式声明(默认返回int类型)。32位int会将64位指针截断为4字节,虽已排除C/C++交互问题,但仍需确认所有文件都正确引入了头文件。 - 编译器优化异常:开启高优化级别(如
-O2、-O3)时,编译器可能对指针做了错误优化,将64位指针按32位处理。可尝试关闭优化(-O0)验证问题是否消失。 - 混合位数目标文件链接:项目中同时存在32位和64位的目标文件,链接后函数调用的栈帧处理出错,导致返回值被截断。
内容的提问来源于stack exchange,提问作者Vivian
相关产品推荐
相关产品推荐

