summaryrefslogtreecommitdiffstats
path: root/kernel/scripts/gdb/linux
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/scripts/gdb/linux')
-rw-r--r--kernel/scripts/gdb/linux/dmesg.py1
-rw-r--r--kernel/scripts/gdb/linux/lists.py92
-rw-r--r--kernel/scripts/gdb/linux/symbols.py9
-rw-r--r--kernel/scripts/gdb/linux/tasks.py20
-rw-r--r--kernel/scripts/gdb/linux/utils.py4
5 files changed, 116 insertions, 10 deletions
diff --git a/kernel/scripts/gdb/linux/dmesg.py b/kernel/scripts/gdb/linux/dmesg.py
index 3c947f0c5..927d0d2a3 100644
--- a/kernel/scripts/gdb/linux/dmesg.py
+++ b/kernel/scripts/gdb/linux/dmesg.py
@@ -12,7 +12,6 @@
#
import gdb
-import string
from linux import utils
diff --git a/kernel/scripts/gdb/linux/lists.py b/kernel/scripts/gdb/linux/lists.py
new file mode 100644
index 000000000..3a3775bc1
--- /dev/null
+++ b/kernel/scripts/gdb/linux/lists.py
@@ -0,0 +1,92 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# list tools
+#
+# Copyright (c) Thiebaud Weksteen, 2015
+#
+# Authors:
+# Thiebaud Weksteen <thiebaud@weksteen.fr>
+#
+# This work is licensed under the terms of the GNU GPL version 2.
+#
+
+import gdb
+
+from linux import utils
+
+list_head = utils.CachedType("struct list_head")
+
+
+def list_check(head):
+ nb = 0
+ if (head.type == list_head.get_type().pointer()):
+ head = head.dereference()
+ elif (head.type != list_head.get_type()):
+ raise gdb.GdbError('argument must be of type (struct list_head [*])')
+ c = head
+ try:
+ gdb.write("Starting with: {}\n".format(c))
+ except gdb.MemoryError:
+ gdb.write('head is not accessible\n')
+ return
+ while True:
+ p = c['prev'].dereference()
+ n = c['next'].dereference()
+ try:
+ if p['next'] != c.address:
+ gdb.write('prev.next != current: '
+ 'current@{current_addr}={current} '
+ 'prev@{p_addr}={p}\n'.format(
+ current_addr=c.address,
+ current=c,
+ p_addr=p.address,
+ p=p,
+ ))
+ return
+ except gdb.MemoryError:
+ gdb.write('prev is not accessible: '
+ 'current@{current_addr}={current}\n'.format(
+ current_addr=c.address,
+ current=c
+ ))
+ return
+ try:
+ if n['prev'] != c.address:
+ gdb.write('next.prev != current: '
+ 'current@{current_addr}={current} '
+ 'next@{n_addr}={n}\n'.format(
+ current_addr=c.address,
+ current=c,
+ n_addr=n.address,
+ n=n,
+ ))
+ return
+ except gdb.MemoryError:
+ gdb.write('next is not accessible: '
+ 'current@{current_addr}={current}\n'.format(
+ current_addr=c.address,
+ current=c
+ ))
+ return
+ c = n
+ nb += 1
+ if c == head:
+ gdb.write("list is consistent: {} node(s)\n".format(nb))
+ return
+
+
+class LxListChk(gdb.Command):
+ """Verify a list consistency"""
+
+ def __init__(self):
+ super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA,
+ gdb.COMPLETE_EXPRESSION)
+
+ def invoke(self, arg, from_tty):
+ argv = gdb.string_to_argv(arg)
+ if len(argv) != 1:
+ raise gdb.GdbError("lx-list-check takes one argument")
+ list_check(gdb.parse_and_eval(argv[0]))
+
+LxListChk()
diff --git a/kernel/scripts/gdb/linux/symbols.py b/kernel/scripts/gdb/linux/symbols.py
index cd5bea965..627750cb4 100644
--- a/kernel/scripts/gdb/linux/symbols.py
+++ b/kernel/scripts/gdb/linux/symbols.py
@@ -14,9 +14,8 @@
import gdb
import os
import re
-import string
-from linux import modules, utils
+from linux import modules
if hasattr(gdb, 'Breakpoint'):
@@ -97,7 +96,7 @@ lx-symbols command."""
return ""
attrs = sect_attrs['attrs']
section_name_to_address = {
- attrs[n]['name'].string() : attrs[n]['address']
+ attrs[n]['name'].string(): attrs[n]['address']
for n in range(int(sect_attrs['nsections']))}
args = []
for section_name in [".data", ".data..read_mostly", ".rodata", ".bss"]:
@@ -124,7 +123,7 @@ lx-symbols command."""
addr=module_addr,
sections=self._section_arguments(module))
gdb.execute(cmdline, to_string=True)
- if not module_name in self.loaded_modules:
+ if module_name not in self.loaded_modules:
self.loaded_modules.append(module_name)
else:
gdb.write("no module object found for '{0}'\n".format(module_name))
@@ -164,7 +163,7 @@ lx-symbols command."""
self.load_all_symbols()
if hasattr(gdb, 'Breakpoint'):
- if not self.breakpoint is None:
+ if self.breakpoint is not None:
self.breakpoint.delete()
self.breakpoint = None
self.breakpoint = LoadModuleBreakpoint(
diff --git a/kernel/scripts/gdb/linux/tasks.py b/kernel/scripts/gdb/linux/tasks.py
index e2037d9bb..862a4ae24 100644
--- a/kernel/scripts/gdb/linux/tasks.py
+++ b/kernel/scripts/gdb/linux/tasks.py
@@ -18,8 +18,8 @@ from linux import utils
task_type = utils.CachedType("struct task_struct")
+
def task_lists():
- global task_type
task_ptr_type = task_type.get_type().pointer()
init_task = gdb.parse_and_eval("init_task").address
t = g = init_task
@@ -38,6 +38,7 @@ def task_lists():
if t == init_task:
return
+
def get_task_by_pid(pid):
for task in task_lists():
if int(task['pid']) == pid:
@@ -65,13 +66,28 @@ return that task_struct variable which PID matches."""
LxTaskByPidFunc()
+class LxPs(gdb.Command):
+ """Dump Linux tasks."""
+
+ def __init__(self):
+ super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)
+
+ def invoke(self, arg, from_tty):
+ for task in task_lists():
+ gdb.write("{address} {pid} {comm}\n".format(
+ address=task,
+ pid=task["pid"],
+ comm=task["comm"].string()))
+
+LxPs()
+
+
thread_info_type = utils.CachedType("struct thread_info")
ia64_task_size = None
def get_thread_info(task):
- global thread_info_type
thread_info_ptr_type = thread_info_type.get_type().pointer()
if utils.is_target_arch("ia64"):
global ia64_task_size
diff --git a/kernel/scripts/gdb/linux/utils.py b/kernel/scripts/gdb/linux/utils.py
index 128c306db..0893b326a 100644
--- a/kernel/scripts/gdb/linux/utils.py
+++ b/kernel/scripts/gdb/linux/utils.py
@@ -83,7 +83,7 @@ def get_target_endianness():
elif "big endian" in endian:
target_endianness = BIG_ENDIAN
else:
- raise gdb.GdgError("unknown endianness '{0}'".format(str(endian)))
+ raise gdb.GdbError("unknown endianness '{0}'".format(str(endian)))
return target_endianness
@@ -151,6 +151,6 @@ def get_gdbserver_type():
gdbserver_type = GDBSERVER_QEMU
elif probe_kgdb():
gdbserver_type = GDBSERVER_KGDB
- if not gdbserver_type is None and hasattr(gdb, 'events'):
+ if gdbserver_type is not None and hasattr(gdb, 'events'):
gdb.events.exited.connect(exit_handler)
return gdbserver_type