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

如何解决Google Test中读取内存地址时的访问违例问题?

问题原因分析

你遇到的0xC0000005访问违例错误,核心原因是直接在用户态测试程序中访问硬件物理地址0x2025111B:

  • 该地址属于硬件寄存器的物理地址,在普通PC的用户态进程中,这个地址并未映射到进程的虚拟地址空间,操作系统会直接阻止这种非法内存访问,触发权限错误。
  • 即便你是在做嵌入式开发,当在PC上运行Google Test时,也没有对应的硬件设备提供这个寄存器,自然无法对该地址进行读写操作。
解决办法

1. 重构代码,用依赖注入解耦硬件操作

把直接访问寄存器的逻辑封装成可替换的接口,避免硬编码物理地址,这样测试时可以用模拟对象替代真实硬件操作。

重构后的核心代码:

// 定义寄存器操作接口
class RegAccessor {
public:
    virtual void setBit(uint32_t bit) = 0;
    virtual ~RegAccessor() = default;
};

// 真实硬件场景的实现
class HardwareRegAccessor : public RegAccessor {
public:
    void setBit(uint32_t bit) override {
        volatile MYREG_t* reg = reinterpret_cast<volatile MYREG_t*>(0x2025111BUL);
        reg->u32reg |= bit;
    }
};

// 原业务逻辑依赖接口,不再直接操作硬件地址
void testcode(RegAccessor& accessor) {
    accessor.setBit(SET_VALUE);
    call_another_funct();
}

配套Google Mock测试用例:

#include <gmock/gmock.h>

class MockRegAccessor : public RegAccessor {
public:
    MOCK_METHOD(void, setBit, (uint32_t bit), (override));
};

TEST_F(sample_test, check) {
    MockRegAccessor mock;
    EXPECT_CALL(mock, setBit(SET_VALUE)).Times(1);
    
    testcode(mock);
}

2. 临时映射模拟寄存器内存(仅简单场景适用)

如果不想大规模重构代码,可以在测试前将目标地址映射到进程可访问的内存区域(以Windows为例):

#include <Windows.h>

TEST_F(sample_test, check) {
    // 分配内存并映射到目标地址,仅用于测试
    void* mappedAddr = VirtualAlloc(reinterpret_cast<void*>(0x2025111B), sizeof(MYREG_t), 
                                    MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    ASSERT_NE(mappedAddr, nullptr) << "内存映射失败";
    
    testcode();
    
    // 测试完成后清理
    VirtualFree(mappedAddr, 0, MEM_RELEASE);
}

注意:这种方式受操作系统地址空间布局限制,不是所有地址都能成功映射,且仅能验证读写逻辑,无法模拟硬件的真实行为。

3. 嵌入式场景:使用硬件模拟器

如果是嵌入式开发场景,推荐用QEMU等硬件模拟器运行测试,让测试程序在模拟的硬件环境中执行,此时0x2025111B地址会被模拟器映射到虚拟硬件寄存器,避免访问违例。

内容的提问来源于stack exchange,提问作者user2986042

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:45:46