0

最近,我一直在重新编写自己的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???????");
}

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

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

4

1 回答 1

0

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

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.

于 2020-11-04T02:41:28.880 回答