Использование структуры вызывает панику ядра?
-
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