You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 13:20:07