Использование структуры вызывает панику ядра?

StackOverflow https://stackoverflow.com/questions/1896935

  •  19-09-2019
  •  | 
  •  

Вопрос

Я впервые пытаюсь написать код ядра Linux, и у меня начинается странная паника ядра.

У меня есть связанный список, который я поддерживаю с помощью встроенных макросов ядра (include/linux/list.h).Если список пуст, я выделяю экземпляр следующей структуры:

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

и укажите на него указателем «tmp».Я добавляю tmp в список, который веду, с помощью list_add_tail().

Позже, если список не пуст (я пытаюсь протестировать с одним элементом списка, чтобы упростить отладку), я указываю на первый элемент списка с помощью tmp и пытаюсь распечатать содержимое tmp->end.tv_sec.К сожалению, это вызывает панику ядра.

tmp не равен NULL (я проверяю во время выполнения), как и «tmp->end» (я могу распечатать оба).Только когда я пытаюсь получить доступ к одному из полей в «конце», я получаю панику ядра.Я никогда раньше не видел ничего подобного, есть ли у кого-нибудь идеи?

Спасибо за любую помощь!

-------РЕДАКТИРОВАТЬ------

Пример кода (он находится в функции, которая будет вызываться повторно):

// .........
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 вам следует поместить структуру 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 - это указатель, указывающий на мусор и поэтому он вылетает?Если у вас установлен отладчик ядра, это легко проверить.

        // .........

    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/linux-kernel-linked-list.html

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top