2009-12-13 2 views
0

Je prends ma première chance d'écrire du code noyau Linux, et je suis confronté à une panique kernel bizarre.L'utilisation de struct provoque la panique du noyau?

J'ai une liste chaînée que je gère avec les macros intégrées du noyau (include/linux/list.h). Si la liste est vide, j'attribuer une instance de la structure suivante:

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

et pointez avec un pointeur appelé « tmp ». J'ajoute tmp à la liste que je maintiens avec list_add_tail(). Plus tard, si la liste n'est pas vide (j'essaie de tester avec un élément de liste pour simplifier le débogage), je pointe vers le premier élément de la liste avec tmp et j'essaie d'imprimer le contenu de tmp-> end.tv_sec. Malheureusement, cela provoque une panique du noyau. Tmp n'est pas NULL (je vérifie au moment de l'exécution) et ni "tmp-> end" (je suis capable d'imprimer les deux). C'est seulement quand j'essaie d'accéder à l'un des champs de "fin" que j'obtiens une panique du noyau. Je n'ai jamais vu quelque chose comme ça avant - quelqu'un a-t-il des idées?

Merci pour toute aide!

------- ------ EDIT

exemple de code (ce vit dans une fonction qui sera appelée à plusieurs reprises):

// ......... 
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)); 
    } 

    // ........ 
+3

un peu de code qui illustre le problème. –

+0

Plus précisément, le code accédant aux champs sur 'tmp-> end' (et le code qui l'entoure). –

+1

Est-ce que vous vérifiez l'adresse de la structure à l'entrée de la liste et quand vous la sortez de la liste? My_list.time_list est-elle initialisée correctement? –

Répondre

4

vous manque quelques éléments fondamentaux à propos des listes chaînées Linux. Les points suivants doivent changer:

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

Pour:

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

Lorsque vous utilisez Linux listes liées, vous devez mettre le list_head struct dans votre struct que vous voulez une liste.
Dans le code ci-dessous, vous affectez un type struct time_span et référençant une variable nommée time_list dans la variable allouée new_time_span ... mais vous n'avez pas ajouté cela à votre structure ci-dessus.

// ......... 
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; 
     } 
    } 

Basé sur les informations que vous avez fournies, je ne sais pas pourquoi les pauses ci-dessus. Peut-être que c'est juste que tmp est un pointeur pointant vers la poubelle et c'est pourquoi il se bloque? Si vous avez une configuration de débogueur de noyau, elle est facile à vérifier.

 // ......... 

    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)); 
    } 

    // ........ 

Voici quelques bons articles qui devraient aider:
http://kernelnewbies.org/FAQ/LinkedLists
http://sumanadak.blogspot.com/2006/09/linux-kernel-linked-list.html

Questions connexes