Получить номера строк из трассировки вызовов ядра - PullRequest
1 голос
/ 16 апреля 2010

Я пытаюсь отладить проблему с очередью завершения:

Apr 14 18:39:15 ST2035 kernel: Call Trace:
Apr 14 18:39:15 ST2035 kernel:  [<ffffffff8049b295>] schedule_timeout+0x1e/0xad
Apr 14 18:39:15 ST2035 kernel:  [<ffffffff8049a81c>] wait_for_common+0xd5/0x13c
Apr 14 18:39:15 ST2035 kernel:  [<ffffffffa01ca32b>]
ib_unregister_mad_agent+0x376/0x4c9 [ib_mad]
Apr 14 18:39:16 ST2035 kernel:  [<ffffffffa03058f4>] ib_umad_close+0xbd/0xfd

Можно ли превратить эти шестнадцатеричные числа во что-то близкое к номерам строк?

1 Ответ

4 голосов
/ 16 апреля 2010

Не совсем, но если у вас собран образ vmlinux с отладочной информацией (например, в RHEL вы сможете установить kernel-debug или kernel-dbg или что-то подобное), вы можете приблизиться. Итак, если у вас есть этот файл vmlinux. Сделайте следующее:

objdump -S vmlinux

При этом будет сложнее всего сопоставить объектный код с отдельными строками исходного кода.

например. для следующего кода C:

#include <stdio.h>
main() {
  int a = 1;
  int b = 2;

  // This is a comment

  printf("This is the print line %d\n", b);
} 

скомпилировано с: cc -g test.c

и затем, запустив objdump -S для получающегося исполняемого файла, я получаю большой вывод, описывающий различные части исполняемого файла, включая следующий раздел:

00000000004004cc <main>:
#include <stdio.h>
main() {
  4004cc:   55                      push   %rbp
  4004cd:   48 89 e5                mov    %rsp,%rbp
  4004d0:   48 83 ec 20             sub    $0x20,%rsp
  int a = 1;
  4004d4:   c7 45 f8 01 00 00 00    movl   $0x1,-0x8(%rbp)
  int b = 2;
  4004db:   c7 45 fc 02 00 00 00    movl   $0x2,-0x4(%rbp)

  // This is a comment

  printf("This is the print line %d\n", b);
  4004e2:   8b 75 fc                mov    -0x4(%rbp),%esi
  4004e5:   bf ec 05 40 00          mov    $0x4005ec,%edi
  4004ea:   b8 00 00 00 00          mov    $0x0,%eax
  4004ef:   e8 cc fe ff ff          callq  4003c0 <printf@plt>
} 

Вы можете сопоставить адреса объектного кода в первом столбце с адресами в трассировке стека. Объедините это с информацией о номере строки, чередующейся в выводе сборки ... и вы там.

Теперь имейте в виду, что это не всегда будет успешным на 100%, потому что kenrel обычно компилируется на уровне оптимизации -O2, и компилятор сделал бы много переупорядочения кода и т. Д. Но если вы знакомы с кодом, который вы пытаетесь отлаживать и имеете некоторое удобство с расшифровкой сборки платформы, на которой работаете ... вы должны быть в состоянии определить большинство ваших сбоев и т. д.

...