سؤال

أنا آخذ صدعي الأول في كتابة بعض كود نواة Linux، وأضرب ذعر نواة غريب.

لدي قائمة مرتبطة، أنا أحافظ على وحدات الماكرو المدمجة في Kernel (بما في ذلك / Linux / List.H). إذا كانت القائمة فارغة، فقد قمت بتخصيص مثيل الهيكل التالي:

struct time_span
{
   struct timeval start;
   struct timeval end;
};

وأشر إليها مع مؤشر يسمى "TMP". أضف TMP إلى القائمة التي أقوم بها مع list_add_tail ().

في وقت لاحق، إذا كانت القائمة غير فارغة (أحاول اختبار عنصر قائمة واحدة لتبسيط التصحيح)، فأشر بالبند الأول في القائمة مع TMP وحاول طباعة محتويات TMP-> Endv_Sec. لسوء الحظ، هذا يسبب الذعر نواة.

TMP ليس فارغا (أتحقق من وقت التشغيل) ولا "إنهاء TMP->" (يمكنني طباعة كليهما). فقط عندما أحاول الوصول إلى إحدى الحقول في "النهاية" التي أحصل على ذعر نواة. لم أر شيئا مثل هذا من قبل - هل لدى أي شخص أي أفكار؟

شكرا لأي مساعدة!

-------تعديل------

مثال الكود (هذا يعيش في وظيفة سيتم استدعاءها بشكل متكرر):

// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
    {
        tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
        if(tmp != NULL)
        {
                    tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
                                                     // Attempting to print "tmp->end.tv_sec" also breaks.
            tmp->end.tv_usec = now_tv.tv_usec;
        }
    }

        // .........

    if(list_empty(&(my_list.time_list)))
        {
        new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
        INIT_LIST_HEAD(&(new_time_span->time_list));
        list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
            do_gettimeofday(&(new_time_span->start));
    }

    // ........
هل كانت مفيدة؟

المحلول

أنت تفتقد بعض الأساسيات حول قوائم Linux المرتبطة. يجب أن يتغير ما يلي:

struct time_span
{
   struct timeval start;
   struct timeval end;
};

ل:

struct time_span
{
   struct timeval start;
   struct timeval end;
   struct list_head time_list;
}

عند استخدام قوائم Linux المرتبطة، يجب عليك وضع قائمة Bucting List_head داخل منظمك الذي تريد قائمة به.
في الكود أدناه، أنت تخصيص نوع struct time_span والرجوع إلى متغير اسمه time_list داخل المتغير المخصص new_time_span... لكنك لم تقم بإضافة ذلك إلى بنية أعلاه.

// .........
struct timeval now_tv;
do_gettimeofday(&now_tv);
if(!list_empty(&(my_list.time_list)))
    {
        tmp = list_first_entry(&(my_list.time_list), struct time_span, time_list);
        if(tmp != NULL)
        {
                    tmp->end.tv_sec = now_tv.tv_sec; // THIS BREAKS
                                                     // Attempting to print "tmp->end.tv_sec" also breaks.
                tmp->end.tv_usec = now_tv.tv_usec;
        }
    }

بناء على المعلومات التي قدمتها، لا أعرف لماذا الفواصل المذكورة أعلاه. ربما هو فقط أن TMP هو مؤشر يشير إلى القمامة وهذا هو السبب في أنها تعطل؟ إذا كان لديك إعداد Debugger Kernel، فمن السهل التحقق من ذلك.

        // .........

    if(list_empty(&(my_list.time_list)))
        {
        new_time_span = (struct time_span *) kmalloc(sizeof(struct time_span), GFP_KERNEL);
        INIT_LIST_HEAD(&(new_time_span->time_list));
        list_add_tail(&(new_time_span->time_list), &(my_list.time_list));
            do_gettimeofday(&(new_time_span->start));
    }

    // ........

فيما يلي بعض المقالات الجيدة التي يجب أن تساعد:
http://kernelnewbies.org/faq/linkedlists.
http://sumanadak.blogspot.com/2006/09/lineux-kernel-linked-linter.html.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top