Commit d6c97087 authored by André Draszik's avatar André Draszik Committed by Linus Torvalds

scripts/gdb: make lx-dmesg command work (reliably)

lx-dmesg needs access to the log_buf symbol from printk.c.
Unfortunately, the symbol log_buf also exists in BPF's verifier.c and
hence gdb can pick one or the other.  If it happens to pick BPF's
log_buf, lx-dmesg doesn't work:

  (gdb) lx-dmesg
  Python Exception <class 'gdb.MemoryError'> Cannot access memory at address 0x0:
  Error occurred in Python command: Cannot access memory at address 0x0
  (gdb) p log_buf
  $15 = 0x0

Luckily, GDB has a way to deal with this, see
  https://sourceware.org/gdb/onlinedocs/gdb/Symbols.html

  (gdb) info variables ^log_buf$
  All variables matching regular expression "^log_buf$":

  File <linux.git>/kernel/bpf/verifier.c:
  static char *log_buf;

  File <linux.git>/kernel/printk/printk.c:
  static char *log_buf;
  (gdb) p 'verifier.c'::log_buf
  $1 = 0x0
  (gdb) p 'printk.c'::log_buf
  $2 = 0x811a6aa0 <__log_buf> ""
  (gdb) p &log_buf
  $3 = (char **) 0x8120fe40 <log_buf>
  (gdb) p &'verifier.c'::log_buf
  $4 = (char **) 0x8120fe40 <log_buf>
  (gdb) p &'printk.c'::log_buf
  $5 = (char **) 0x8048b7d0 <log_buf>

By being explicit about the location of the symbol, we can make lx-dmesg
work again.  While at it, do the same for the other symbols we need from
printk.c

Link: http://lkml.kernel.org/r/20170526112222.3414-1-git@andred.netSigned-off-by: default avatarAndré Draszik <git@andred.net>
Tested-by: default avatarKieran Bingham <kieran@bingham.xyz>
Acked-by: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 864b9a39
...@@ -23,10 +23,11 @@ class LxDmesg(gdb.Command): ...@@ -23,10 +23,11 @@ class LxDmesg(gdb.Command):
super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA) super(LxDmesg, self).__init__("lx-dmesg", gdb.COMMAND_DATA)
def invoke(self, arg, from_tty): def invoke(self, arg, from_tty):
log_buf_addr = int(str(gdb.parse_and_eval("log_buf")).split()[0], 16) log_buf_addr = int(str(gdb.parse_and_eval(
log_first_idx = int(gdb.parse_and_eval("log_first_idx")) "'printk.c'::log_buf")).split()[0], 16)
log_next_idx = int(gdb.parse_and_eval("log_next_idx")) log_first_idx = int(gdb.parse_and_eval("'printk.c'::log_first_idx"))
log_buf_len = int(gdb.parse_and_eval("log_buf_len")) log_next_idx = int(gdb.parse_and_eval("'printk.c'::log_next_idx"))
log_buf_len = int(gdb.parse_and_eval("'printk.c'::log_buf_len"))
inf = gdb.inferiors()[0] inf = gdb.inferiors()[0]
start = log_buf_addr + log_first_idx start = log_buf_addr + log_first_idx
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment