【问题标题】:Criterion unit tests for memory addresses内存地址的标准单元测试
【发布时间】:2021-02-16 18:01:23
【问题描述】:

最近我一直在重新编写自己的 printf 函数,并使用 Criterion C 库进行单元测试。

当我尝试测试%p 标志(打印指针的地址)时,我只是被困在那里试图弄清楚如何预测我将拥有的内存地址。

我不确定是否可以在标准开始测试之前“提取”它并将其发送到断言中,但文档中似乎没有关于指针、内存地址或任何相关内容的内容。

对于 nil 指针,我可以预测结果(“nil”字符串),例如:

Test(my_printf, nil_pointer, .init=cr_redirect_stdout)
{
    char *string = NULL;

    my_printf("This is a nil %p.", string);
    cr_assert_stdout_eq_str("This is a nil (nil).");
}

但是对于一个未知的未来内存地址,我只是卡住了:

Test(my_printf, pointer_address_1, .init=cr_redirect_stdout)
{
    char *string = "hello world";

    my_printf("valid pointer: %p.", string);
    cr_assert_stdout_eq_str("valid pointer: 0x???????");
}

我想知道是否有办法在测试期间预测/将指针的地址发送到我的断言中,而不是问号。

我不知道我是否很清楚,如果没有,请告诉我,以便我帮助您理解我的问题。

【问题讨论】:

    标签: c unit-testing pointers memory-address criterion


    【解决方案1】:

    为什么你想要一个“真正的”指针呢?您可以很好地制作自己的假指针,毕竟指针只是一个值。如果你的实现是合理的,你的打印函数真的不需要知道指针是否有效就可以打印它的值。

    Test(my_printf, pointer_address_1, .init=cr_redirect_stdout)
    {
        my_printf("pointer: %p", (void *)0x12345678);
        cr_assert_stdout_eq_str("pointer: 0x12345678");
    }
    

    如果您真的想使用有效指针进行测试,那么您可以尝试使用mmap 来请求特定地址的页面,但这是 Linux 特定的,完全不需要:

    Test(my_printf, pointer_address_1, .init=cr_redirect_stdout)
    {
        unsigned char *ptr = mmap(0x12345000, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
        if (ptr == MAP_FAILED) {
            // Fail test
        }
    
        ptr += 0x678;
        my_printf("pointer: %p", ptr);
        cr_assert_stdout_eq_str("pointer: 0x12345678");
    }
    

    请注意,mmap 仅将您请求的地址作为提示,也仅映射整个页面,因此地址的最后 3 个十六进制数字将始终为 000

    【讨论】:

    • 非常感谢您回答我的问题。问题是我不太熟悉内存地址,它的真实外观,它的长度等等......我刚刚看到printf%p标志只是以十六进制打印字符串,那就是我在自己的版本中所做的,只是在开始时使用我自己的%x 标志并打印0x,但我不是100% 确定每次都会这样。我将更深入地使用mmap 函数来了解它是如何工作的,指针及其内存地址也是如此。
    • @pironc 正如我所说,您不需要需要mmap。真正的printf当然不会用,真的用起来有点疯狂。您可以将指针的值转换为整数类型(如 uintmax_t ,然后像处理任何其他整数一样以十六进制打印它)。无需使用有效指针进行测试。
    猜你喜欢
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 2014-08-05
    • 2011-08-04
    • 2018-12-19
    • 1970-01-01
    相关资源
    最近更新 更多