-1

我目前正在调试 C 代码。这基本上是来自数据收集平台的客户端,我从链接列表中读取到奇怪的错误。问题基本上是最后一项的“下一个”指针在某个未知点从 NULL 更改为 0xFFFFFFFFF。然后我尝试使用地址清理程序编译我的库,以便找到错误错误可能在哪里并且错误消失了,或者最好说错误当前是隐藏的。可能吗?Asan 库如何影响代码以使其不崩溃?提前致谢。

编辑:抱歉描述不佳,我会尝试更深入。我一直在调试代码,我发现问题出在哪里。它位于 json 配置文件的解析函数中(为此我使用 jansson 库)。json格式是这样的:

{
...
"version": {
            "software": "0.2",
            "firmware": "0.2"
        },     
"system": ["system_A", "system_B"],
...
"internal_devices : [
         {
             ...
             "version": {
                 "software": "0.2",
                 "firmware": "0.2"
             },     
             "system": ["system_B"],
             ...
             },
             ...
             "version" : {
                 "software": "0.2",
                 "firmware": "0.2"
              },     
              "system": ["system_A"],
               ...
               }
           ]
      }
}   

我有一个这样的结构来存储这些数据

typedef struct XXX_NODE {
    mqtt_client_t * client;
    XXX_Device devices[XXX_MAX_DEVICES];
    size_t num_devices;
    XXX_operation_mode mode;
    pthread_mutex_t callback_lock;
    pthread_mutex_t registration_lock;
    pthread_cond_t registration_condition;
}XXX_NODE;

typedef struct XXX_id {
    ...
    struct XXX_parent parent_unit;
    // char parent_fin[64];
    int internal_level_tree;
    XXX_version version;
    List XXX_systems;
    List extended_topics;
    bool registered;
}XXX_id;

真正的问题在于列表 XXX_systems。我每个设备都有一个列表,我可以在同一个结构中拥有多个设备,其中第一个元素(在 XXX_Device 设备数组中)是主要单元。正是在这个设备中,我丢失了信息。解析功能看起来工作正常。在函数结束时,结构具有权限值,但是当我释放 json“对象”时,我失去了 的引用XXX_systems->next,但奇怪的是,如果我不释放一些 json“对象”,一切正常.. .

因此,在这种情况下,我丢失了信息:

json_decref(internal_list);
json_decref(unit);
json_decref(root);
return 0;

但是如果我这样评论 json_decref

json_decref(internal_list);
//json_decref(unit);
json_decref(root);
return 0; 

一切正常...

4

1 回答 1

0

从您的描述看来,调用 tojson_decref()会导致数据损坏。显然,由变量标识的某些数据unit被破坏,然后您尝试使用它,可能来自某些单独的代码。

我可以看到两种最可能的情况:

  • 要么您拥有多个数据的“用户”,并且您可能不关心在“用户”中正确识别“所有者”,因此有些人决定删除仍在使用的数据;
  • 或者,您忘记识别某些用户,因此数据对象在某些时候似乎未使用并在有人仍然引用它时被删除。

我对底层的 Jansson 问题一无所知,但我只是简单地询问了 Google json_decref,它找到了 Jansson 库描述。请参阅有关引用计数的部分:

https://jansson.readthedocs.io/en/2.8/apiref.html#reference-count

那里清楚地说明了json_decref()减少引用计数并在计数降至零时删除对象。以下注释描述了创建所谓的借用引用,并指出此类引用的持有者必须调用json_incref(). 这可以防止对象在使用时被删除。一旦不再需要该值,就json_decref()应该调用以释放引用(并且可能删除数据对象)。

结论是您很可能错过json_incref()了一些存储参考以供将来使用的代码。结果,引用计数太低并且过早归零,导致过早删除。这是第二个场景。

扫描您的代码和数据结构以查找对 Json 数据对象的存储引用,并确保每次存储非空引用时调用json_incref()它,并且每次非空引用被覆盖或超出调用范围时json_decref()

注意:
仔细区分借用的参考被盗的参考——后者也在链接的文档页面中描述。

PS
看来您的问题与 C 语言无关,而是与 Jansson 库的不当使用有关。请考虑删除不必要的标签。

于 2020-04-06T08:29:21.560 回答