对函数指针的断言失败

问题描述 投票:0回答:1

我正在使用 Signal 的 libsignal 库,试图猜测如何编译和运行一个小玩具程序。然而,我一开始就陷入困境。我知道我必须用指向稍后在库中使用的函数的指针填充变量,即使我试图复制库在测试中的功能,我也看不出测试和测试之间有什么区别我的代码,以及为什么我的程序在运行时失败。我正在使用的代码如下:

#include <stdlib>
#include <signal/signal_protocol.h>
#include <signal/key_helper.h>
#include <openssl/rand.h>

int random(uint8_t *data, size_t len, void *user_data)
{
    if(RAND_bytes(data, len)) {
        return 0;
    }
    else {
        return SG_ERR_UNKNOWN;
    }
}

int main(int argc, char **argv) {
    signal_crypto_provider provider = {
            .random_func = random
            /*.hmac_sha256_init_func = HMAC_CTX_new,
            .hmac_sha256_update_func = HMAC_Update,
            .hmac_sha256_final_func = HMAC_Final,
            .hmac_sha256_cleanup_func = HMAC_CTX_free,
            .sha512_digest_init_func = SHA512_Init,
            .sha512_digest_update_func = SHA512_Update,
            .sha512_digest_final_func = SHA512_Final,
            .sha512_digest_cleanup_func = EVP_MD_CTX_free,
            .encrypt_func = EVP_aes_256_cbc,
            .decrypt_func = EVP_aes_256_cbc,
            .user_data = 0*/
    };

    signal_context *global_context;
    signal_context_create(&global_context, 0);
    signal_context_set_crypto_provider(global_context, &provider);
    //signal_context_set_locking_functions(global_context, lock_function,
    //unlock_function);


    ratchet_identity_key_pair *identity_key_pair;
    uint32_t registration_id;
    signal_protocol_key_helper_pre_key_list_node *pre_keys_head;
    session_signed_pre_key *signed_pre_key;


    signal_protocol_key_helper_generate_identity_key_pair(
        &identity_key_pair,
        global_context
    );

    exit(EXIT_SUCCESS);

}

当程序达到

signal_protocol_key_helper_generate_identity_key_pair
时,问题就出现了。浏览该库并跟踪它所做的调用,我最终得到了以下函数:

int signal_crypto_random(signal_context *context, uint8_t *data, size_t len)
{
    assert(context);
    assert(context->crypto_provider.random_func);
    return context->crypto_provider.random_func(data, len, context->crypto_provider.user_data);
}

失败的断言是第二个,给我以下错误:

signal_crypto_random: Assertion `context->crypto_provider.random_func' failed.

我能想到的唯一解释——我对 C 有点陌生——是指针不指向我之前指定的函数。如果这个猜测是正确的,为什么会发生这种情况?

检查他们的测试代码,并将其与我的代码进行比较,我看不出是什么造成了导致我的程序失败的关键差异。调试时,变量似乎有正确的内容。

Variable contents

谢谢你。


测试通用.c

void setup_test_crypto_provider(signal_context *context)
{
    signal_crypto_provider provider = {
            .random_func = test_random_generator,
            .hmac_sha256_init_func = test_hmac_sha256_init,
            .hmac_sha256_update_func = test_hmac_sha256_update,
            .hmac_sha256_final_func = test_hmac_sha256_final,
            .hmac_sha256_cleanup_func = test_hmac_sha256_cleanup,
            .sha512_digest_init_func = test_sha512_digest_init,
            .sha512_digest_update_func = test_sha512_digest_update,
            .sha512_digest_final_func = test_sha512_digest_final,
            .sha512_digest_cleanup_func = test_sha512_digest_cleanup,
            .encrypt_func = test_encrypt,
            .decrypt_func = test_decrypt,
            .user_data = 0
    };

    signal_context_set_crypto_provider(context, &provider);
}

测试-common-openssl.c

int test_random_generator(uint8_t *data, size_t len, void *user_data)
{
    if(RAND_bytes(data, len)) {
        return 0;
    }
    else {
        return SG_ERR_UNKNOWN;
    }
}
c signals assertion
1个回答
2
投票

signal_context_set_crypto_provider()
中有一个检查:

if(!crypto_provider
        || !crypto_provider->hmac_sha256_init_func
        || !crypto_provider->hmac_sha256_update_func
        || !crypto_provider->hmac_sha256_final_func
        || !crypto_provider->hmac_sha256_cleanup_func) {
    return SG_ERR_INVAL;
}

所以,答案是你不能不设置这些回调,这就是为什么没有任何内容被复制到上下文并且

assert()
最终会触发。

我理解为什么测试代码不检查返回代码,但在生产代码中,您需要检查返回值以密切关注错误 - 这被认为是一个很好的做法。

© www.soinside.com 2019 - 2024. All rights reserved.