構造体を使用すると、カーネルパニックの原因は?
-
19-09-2019 - |
質問
私はいくつかのLinuxカーネルのコードを書くことで私の最初の亀裂を取っている、と私は奇妙なカーネルパニックを打っています。
私は、カーネルの組み込みマクロを維持していますリンクリストを持っている(/ linuxの/ list.hが含まれます)。リストが空の場合、私は次の構造のインスタンスを割り当てます:
struct time_span
{
struct timeval start;
struct timeval end;
};
と「TMP」と呼ばれるポインタでそれをポイントします。私は()list_add_tailを維持していリストにTMPを追加します。
リストが空でない場合は、その後、私はTMPと、リストの最初の項目を指して(私はデバッグを簡単にするために1つのリスト項目でテストしようとしている)とtmp-の内容をプリントアウトしてみてください>終了.tv_sec。残念ながら、これはカーネルパニックが発生します。
tmpがNULLではないではありません(私は実行時にチェック)とどちらも「tmp->最後は」(私は両方を印刷することができています)です。私はカーネルパニックを取得し、「終了」のフィールドのいずれかにアクセスしようとすると、それだけです。前に私はこのようなものを見たことがない - ?誰もが任意のアイデアを持っていない。
どのような援助をありがとう!
------- EDIT ------
コード例(これは繰り返し呼び出される関数に住んでいる):
// .........
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のカーネルにリンクされた-するlist.htmlする