【问题标题】:hash_add crashes the systemhash_add 使系统崩溃
【发布时间】:2019-10-31 10:32:33
【问题描述】:

当我将一个元素添加到我的哈希表时,它会导致系统内核崩溃,我无法找出它的原因。

我正在编写一些代码来在内核模式下进行一些网络数据包嗅探,并将统计信息存储在一个结构中,了解每个通过我的嗅探器的数据包流。

我的哈希表是这样定义的:

DEFINE_HASHTABLE(flow_dictionary, 10);

后来初始化为:

hash_init(flow_dictionary);

我的数据结构是用

定义的
struct flow_action_head {
    unsigned int flowID;

    /* Mode of operations */
    SELECTION_MODE sampling_mode;
    SELECTION_MODE normalization_mode;

    /* Statistics */
    unsigned int numberPackets;
    unsigned int timeFirstPacket;
    unsigned int timeLastPacket;
    unsigned int packetsReceived;
    unsigned int packetsProcessed;

    /* Pointer to action details */
    nas_t* next;

    /* Required for linked hash list */
    struct hlist_node hash_list;

}; // __attribute__((packed));

在我做的功能中:

void map_add_flow(unsigned int flowID) {

    struct flow_action_head* fah;

    fah = (struct flow_action_head*) kzalloc(sizeof(struct flow_action_head), GFP_ATOMIC);

    fah->flowID = flowID;
    fah->sampling_mode = SMODE_COUNT_BASED;
    fah->normalization_mode = NMODE_TTL;
    fah->numberPackets = 1;
    fah->timeFirstPacket = 0;
    fah->timeLastPacket = 0;
    fah->packetsReceived = 0;
    fah->packetsProcessed = 0;
    fah->next = NULL;

    hash_add(flow_dictionary, &fah->hash_list, flowID);
}

我一点击hash_add,系统就崩溃了。

我希望它只是使用flowID 作为键将记录添加到哈希表flow_dictionary。我不明白为什么它会在这一点上崩溃。结构似乎没问题,我可以读/写flow_action_head 结构的每个值。

【问题讨论】:

  • 如果它崩溃了,那么你会在控制台上显示一个原因和堆栈跟踪。
  • 你为什么在内核模式下这样做而不是使用pcap
  • 您缺少 DEFINE_HASHTABLE 宏、struct hlist_nodehash_add 的定义。 Edit 将您的问题设为minimal reproducible example。是在调用hash_add 之前崩溃,还是进入函数后崩溃?
  • @1201ProgramAlarm - 'DEFINE_HASHTABLE'、'struct hlist_node' 和 'hash_add' 是 linux 内核头文件('/include/linux/hashtable.h' 和 '/include/linux/types)的一部分。H' )。它在进入“hash_add”函数时崩溃。当我评论该行时,代码运行没有任何问题(除了它没有做我需要做的事情)。
  • 崩溃的原因可能在您的其他代码中,您没有向我们展示。这在 Linux 内核编程中以错误的方式编写某些代码并不少见,但它会正常工作......直到其他一些代码命中“完全不同的内存位置”请提供minimal reproducible example

标签: c linux kernel hashtable


【解决方案1】:

我不知道你的背景,所以我假设最少。

你熟悉kgdb吗?如果没有,您可能需要自我介绍一下。

我经常看到报告“当我调用这个函数时它崩溃了”;在调试器中浏览之后,事实证明“当我调用时”意味着 +- 几千个中断和数百万个操作码。您需要在 hash_add() 返回时设置一个断点。

如果您还没有准备好深入研究 kgdb;您可以在此调用之后从 printk() 开始;该消息的存在提供了重要线索: 1.在hash_add返回之前你真的崩溃了吗?如果你能看到你的信息,你肯定是从插入中回来的。 2. 如果你成功了,你会从你的调用中得到一个时间戳,你可以将它与内核崩溃的时间戳进行比较。

通常,内核崩溃时会提供比“我崩溃了”更多的信息。有时它会说明崩溃的位置、崩溃的原因、执行位置的堆栈跟踪。所有这些信息都有助于确定崩溃的根本原因。

FWIW;查看您发布的代码,我看不出有什么问题。我遍历了哈希值,看来您使用它没问题。我怀疑您应该查看从该哈希列表中删除或查找内容的点。祝你好运,狩猎愉快。

【讨论】:

    猜你喜欢
    • 2015-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-23
    • 2013-03-31
    • 2019-07-12
    • 2013-04-01
    • 2020-12-31
    相关资源
    最近更新 更多