Как отлаживать ошибки страниц в ядре Linux

#linux #debugging #kernel #powerpc

#linux #отладка #ядро #powerpc

Вопрос:

В настоящее время я столкнулся с некоторыми уродливыми сбоями ядра при перезагрузке. Я запускаю пользовательский дизайн на основе MPC5200. Я получаю сообщения OOPS, подобные этому:

 VM: Either in interrupt or mm = NULL. mm=0xc0196520 in interrupt: 1
VM: Access of bad area @0x6e615c75
Oops: kernel access of bad area, sig: 11
NIP: C00302E4 XER: 20000000 LR: C00F15D4 SP: C6207B30 REGS: c6207a80 TRAP: 0300    Not tainted
MSR: 00009032 EE: 1 PR: 0 FP: 0 ME: 1 IR/DR: 11
DAR: 6E615C75, DSISR: 20000000
TASK = c6206000[4778] 'SimpleServer2' Last syscall: 102
last math c6206000 last altivec 00000000
GPR00: 7C74696B C6207B30 C6206000 6E615C5D 00000000 00000000 C01BFE68 00000001
GPR08: F0000500 C7CD1600 FFFFFFE3 C7CD1600 00000001 10152540 10100000 10100000
GPR16: C01B0000 00000000 C6207E48 000016D0 00001032 06207BF0 00000000 C0005CC0
GPR24: C0006DCC C6207EA0 C01B0000 C0190000 C0190000 C01D0000 C56A2220 00000001
Call backtrace:
C0018034 C00F1608 C00F6738 C0017D08 C0006EFC C0005CC0 C6207EA0
C011040C C012FEC4 C00EDC7C C00EF078 C00EF518 C0005A7C 10089C18
1001DFAC 10015660 10000608 10003E68 1000804C 10085A0C 100BC020
Kernel panic: Aiee, killing interrupt handler!
In interrupt handler - not syncing
<0>Rebooting in 1 seconds..
  

Эти трассировки OOPS возникают при высокой нагрузке на сеть.
Основная проблема, с которой я столкнулся, заключается в том, что функция do_page_fault вызывается механизмом исключения mmu, и поэтому контекст стека в gdb ненадежен. После отладки и добавления распечаток я выяснил, что процессор, похоже, находится в контексте прерывания. И, следовательно, эта ошибка не подлежит восстановлению.

Насколько я понимаю трассировку OOPS, адрес, который вызывает oops, хранится в регистре DAR: DAR: 6E615C75.

Как я могу получить информацию с этого адреса? Я пытался разобрать адрес в gdb, но он не сопоставлен ни с одной функцией.

Если кому-то интересно узнать о формате OOPS, это генерируется устаревшим ядром 2.4.25, но я думаю, что механизм должен быть таким же, как в ядре 2.6.

Ответ №1:

По определению, если ошибка вашей страницы произошла по этому адресу в контексте прерывания, в этом нет ничего полезного (т. Е. нет смысла пытаться вычислить данные, на которые указывает неверный указатель). Вам нужно разобрать код, ведущий к NIP (C00302E4), и посмотреть, откуда он получил этот адрес и что он пытался сделать.

Комментарии:

1. Да, но в последнем OOPS я получил адрес в NIP, указывающий на do_page_fault, и поэтому я не отправил мне никакого запроса. Но я проверю содержимое NIP для следующего OOPS и разберу его.

2. Ваше право, я что-то перепутал, текущий nip в BDM / GDB указывает на do_page_fault, но сохраненное состояние в * regs указывает на состояние до сбоя, спасибо.

Ответ №2:

Обратите внимание, что значение в DAR подозрительно похоже на фрагмент строки ASCII. На самом деле, это выглядит как смещение на 24 от значения в GPR03 , 0x6E615C5D == "na]" .

Я подозреваю, что у вас есть строка, переполняющая struct указатель, и инструкция по исправлению ошибок разыменовывает элемент этой структуры со смещением 24.