【问题标题】:How to solve address boundary error when adding to `dict` of Redis?添加到Redis的`dict`时如何解决地址边界错误?
【发布时间】:2020-03-10 03:03:03
【问题描述】:

我想根据dict 做一些基本的 put/get 测试。但是在做dictAdd的时候,报错了。

代码

// dict_test.c
#include <stdio.h>
#include "dict.h"

int main(int argc, char *argv[]) {
    // create
    dictType hashDictType;
    dict *d = dictCreate(&hashDictType, NULL);
    printf("Created: %s\n", d == NULL ? "Failed" : "OK");
    // put
    char key[] = "hello";
    char value[] = "world";
    dictAdd(d, key, value);
    return 0;
}

错误信息

'./dict_test' 被信号 SIGSEGV 终止(地址边界错误)

GCC 版本

Apple LLVM 版本 10.0.1 (clang-1001.0.46.4)

编译命令

gcc dict_test.c dict.c zmalloc.c siphash.c  -o dict_test

我发现执行dictIsRehashing(d) 时抛出的错误是一个宏(#define dictIsRehashing(d) ((d)-&gt;rehashidx != -1))。

所以我尝试直接打印d-&gt;rehashidx。但我仍然遇到同样的错误。

printf("%ld \n", d->rehashidx);
printf("%s", ((d)->rehashidx) == -1L ? "False" : "True");

输出

Created: OK
-1 
fish: './dict_test' terminated by signal SIGSEGV (Address boundary error)

也许这是一个基本的 c 问题。任何提示将不胜感激。

复制步骤

  1. 我下载了Redis的源代码:)。
  2. 将演示代码粘贴到src目录下。

【问题讨论】:

  • 当你遇到崩溃时,你应该做的第一件事是在调试器中运行,这样你就可以在崩溃发生时捕捉到它并在你的代码中找到它发生的位置。然后您还可以检查变量及其值,看看它们是否有任何明显的问题。至少,请尝试创建一个minimal reproducible example 向我们展示,包括崩溃的位置和涉及的变量的值。
  • @Someprogrammerdude 我已经更新了。在此过程中,您应该下载 Redis 源代码。 :)
  • 你应该传递sds类型的键和值。
  • @for_stack 问题是我没有初始化哈希函数。非常感谢。

标签: c redis


【解决方案1】:

OP 的解决方案。

问题是当使用dict 时,需要自行初始化哈希函数,我认为它有一个默认值。通过定义一个hash函数,解决了crash问题。

#include <stdio.h>
#include <strings.h>
#include "dict.h"

// a hash function defined
uint64_t dictSdsCaseHash(const void *key) {
    // refer to "siphash.c"
    return dictGenCaseHashFunction((unsigned char*)key, (int) strlen((char*)key));
}

int main(int argc, char *argv[]) {
    // create
    dictType hashDictType;
    hashDictType.hashFunction = dictSdsCaseHash;
    dict *d = dictCreate(&hashDictType, NULL);
    printf("Created: %s\n", d == NULL ? "Failed" : "OK");
    // put
    char key[] = "hello";
    char value[] = "world";
    dictAdd(d, key, value);
    // get
    dictEntry *entry = dictFind(d, key);
    printf("Value: %s\n", entry->v);
    return 0;
}

输出

Created: OK
hello 
Value: world

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-03
    • 1970-01-01
    相关资源
    最近更新 更多