c++ 如何解决google测试中阅读位置的访问违规问题?

q5iwbnjs  于 2023-02-01  发布在  Go
关注(0)|答案(1)|浏览(173)

我正在尝试用下面的代码运行谷歌测试。我正在用类似下面例子的代码阅读一些寄存器值的内存位置。
头文件:

typedef union MYREG
{
  uint32_t u32reg;
  uint8_t  au8byte[4];
} MYREG_t;

#define SET_VALUE       (0x00000002)
#define TEST_REGISTER   ((volatile MYREG_t*)0x2025111BUL)

在代码中,我阅读和写入值为

void testcode()
{
  TEST_REGISTER->u32reg |= SET_VALUE;
  call_another_funct();
}

当我试图通过为这个函数编写一个测试用例来运行google测试时

TEST_F(sample_test, check)
{
  testcode();
}

我低于SEH错误

First-chance exception at 0x0036B28F in test.exe: 0xC0000005: Access violation reading location 0x2025111B.
Unknown file: error: SEH exception with code 0xC0000005 thrown in the test body.

这里出了什么问题?任何建议都将有助于我理解这个错误.

ycl3bljg

ycl3bljg1#

单元可测试性的依赖注入示例:

#include <memory>
#include <utility>

//-----------------------------------------------------------------------------
// define an interface (abstract base class) to communicate with your register
class register_itf
{
public:
    virtual ~register_itf() = default;

    virtual void write(const std::uint32_t value) = 0;
    virtual std::uint32_t read() const noexcept = 0;

protected:
    register_itf() = default;
};

//-----------------------------------------------------------------------------
// toy example of real register

class hardware_register final :
    public register_itf
{
public:
    explicit hardware_register(std::uint32_t* address) :
        m_address(address)
    {
    }
    ~hardware_register() override = default;

    void write(const std::uint32_t value) override
    {
        *m_address = value;
    }

    std::uint32_t read() const noexcept override
    {
        return *m_address;
    }

private:
    volatile std::uint32_t* m_address;
};

//-----------------------------------------------------------------------------
// you can also make this a google mock to test if it has been called etc...

class simulated_register final :
    public register_itf
{
public:
    simulated_register() = default;
    ~simulated_register() override = default;

    void write(const std::uint32_t value) override
    {
        m_value = value;
    }

    std::uint32_t read() const noexcept override
    {
        return m_value;
    }
    
private:
    std::uint32_t m_value;
};

//-----------------------------------------------------------------------------
// a device with a register, use dependency injection
// to inject a real or a simulated register

class device_t
{
public:
    explicit device_t(std::unique_ptr<register_itf>&& reg) :
        m_register(std::move(reg))
    {
    }

    void reset()
    {
        m_register->write(0x01);
    }

private:
    std::unique_ptr<register_itf> m_register;
};

int main()
{
    // production code on real hardware
    //device_t device{ std::make_unique<hardware_register>(0x2025111BUL) };
    
    // unit test code
    device_t device{ std::make_unique<simulated_register>() };

    // functional code using the register will be the same on production/test
    device.reset();

    return 1;

}

相关问题