简体   繁体   English

如何解决谷歌测试中的访问冲突读取位置?

[英]How to solve access violation reading location in google test?

I am trying to run Google test with the below code.我正在尝试使用以下代码运行 Google 测试。 I am reading some memory location for register value with code similar to the examples below.我正在阅读一些 memory 位置的寄存器值,代码类似于下面的示例。

Header file: Header 档案:

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

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

In code I am reading and writing values as在代码中,我正在读取和写入值

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

When i try to run google test by writing a test case for this function当我尝试通过为此 function 编写测试用例来运行谷歌测试时

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

I am getting below SEH error我遇到了 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.

What is going wrong here?这里出了什么问题? Any suggestion would helpful for me to understand the error.任何建议都有助于我理解错误。

Example of dependency injection for unit testability:单元可测试性的依赖注入示例:

#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;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM