Hi Andrew,
please include the following enhancements, fixes and cleanups for the
gdb scripts in your queue. Most work was done by Thiébaud, adding a list
checker and basic process listing.
Jan
CC: =?UTF-8?q?Thi=C3=A9baud=20Weksteen?= <[email protected]>
Jan Kiszka (2):
scripts/gdb: Also allow list_head pointer as lx-list-check paramter
scripts/gdb: Enable completion for lx-list-check parameter
Thiébaud Weksteen (5):
scripts/gdb: Add command to check list consistency
scripts/gdb: Fix typo in exception name
scripts/gdb: Fix PEP8 compliance
scripts/gdb: Add ps command
scripts/gdb: Remove useless global instruction
scripts/gdb/linux/dmesg.py | 1 -
scripts/gdb/linux/lists.py | 92 ++++++++++++++++++++++++++++++++++++++++++++
scripts/gdb/linux/symbols.py | 9 ++---
scripts/gdb/linux/tasks.py | 20 +++++++++-
scripts/gdb/linux/utils.py | 4 +-
scripts/gdb/vmlinux-gdb.py | 1 +
6 files changed, 117 insertions(+), 10 deletions(-)
create mode 100644 scripts/gdb/linux/lists.py
--
2.1.4
From: Thiébaud Weksteen <[email protected]>
Add a gdb script to verify the consistency of lists.
Signed-off-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/lists.py | 89 ++++++++++++++++++++++++++++++++++++++++++++++
scripts/gdb/vmlinux-gdb.py | 1 +
2 files changed, 90 insertions(+)
create mode 100644 scripts/gdb/linux/lists.py
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py
new file mode 100644
index 0000000..2a94b54
--- /dev/null
+++ b/scripts/gdb/linux/lists.py
@@ -0,0 +1,89 @@
+#
+# gdb helper commands and functions for Linux kernel debugging
+#
+# list tools
+#
+# Copyright (c) Thiebaud Weksteen, 2015
+#
+# Authors:
+# Thiebaud Weksteen <[email protected]>
+#
+# 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
+ c = head
+ if (c.type != list_head.get_type()):
+ raise gdb.GdbError('The argument should be of type (struct list_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)
+
+ 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/scripts/gdb/vmlinux-gdb.py b/scripts/gdb/vmlinux-gdb.py
index 4848928..ce82bf5 100644
--- a/scripts/gdb/vmlinux-gdb.py
+++ b/scripts/gdb/vmlinux-gdb.py
@@ -28,3 +28,4 @@ else:
import linux.dmesg
import linux.tasks
import linux.cpus
+ import linux.lists
--
2.1.4
This makes the usage more flexible.
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/lists.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py
index 2a94b54..71fba6a 100644
--- a/scripts/gdb/linux/lists.py
+++ b/scripts/gdb/linux/lists.py
@@ -20,9 +20,11 @@ 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
- if (c.type != list_head.get_type()):
- raise gdb.GdbError('The argument should be of type (struct list_head)')
try:
gdb.write("Starting with: {}\n".format(c))
except gdb.MemoryError:
--
2.1.4
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/lists.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/lists.py b/scripts/gdb/linux/lists.py
index 71fba6a..3a3775b 100644
--- a/scripts/gdb/linux/lists.py
+++ b/scripts/gdb/linux/lists.py
@@ -80,7 +80,8 @@ class LxListChk(gdb.Command):
"""Verify a list consistency"""
def __init__(self):
- super(LxListChk, self).__init__("lx-list-check", gdb.COMMAND_DATA)
+ 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)
--
2.1.4
From: Thiébaud Weksteen <[email protected]>
Signed-off-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/utils.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
index 128c306..d7ff3a3 100644
--- a/scripts/gdb/linux/utils.py
+++ b/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
--
2.1.4
From: Thiébaud Weksteen <[email protected]>
Signed-off-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/dmesg.py | 1 -
scripts/gdb/linux/symbols.py | 9 ++++-----
scripts/gdb/linux/tasks.py | 2 ++
scripts/gdb/linux/utils.py | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/scripts/gdb/linux/dmesg.py b/scripts/gdb/linux/dmesg.py
index 3c947f0..927d0d2 100644
--- a/scripts/gdb/linux/dmesg.py
+++ b/scripts/gdb/linux/dmesg.py
@@ -12,7 +12,6 @@
#
import gdb
-import string
from linux import utils
diff --git a/scripts/gdb/linux/symbols.py b/scripts/gdb/linux/symbols.py
index cd5bea9..627750c 100644
--- a/scripts/gdb/linux/symbols.py
+++ b/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/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index e2037d9..89d38e1 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -18,6 +18,7 @@ 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()
@@ -38,6 +39,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:
diff --git a/scripts/gdb/linux/utils.py b/scripts/gdb/linux/utils.py
index d7ff3a3..0893b32 100644
--- a/scripts/gdb/linux/utils.py
+++ b/scripts/gdb/linux/utils.py
@@ -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
--
2.1.4
From: Thiébaud Weksteen <[email protected]>
Signed-off-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/tasks.py | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index 89d38e1..3191f47 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -67,6 +67,22 @@ 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
--
2.1.4
From: Thiébaud Weksteen <[email protected]>
Signed-off-by: Thiébaud Weksteen <[email protected]>
Signed-off-by: Jan Kiszka <[email protected]>
---
scripts/gdb/linux/tasks.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/scripts/gdb/linux/tasks.py b/scripts/gdb/linux/tasks.py
index 3191f47..862a4ae 100644
--- a/scripts/gdb/linux/tasks.py
+++ b/scripts/gdb/linux/tasks.py
@@ -20,7 +20,6 @@ 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
@@ -89,7 +88,6 @@ 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
--
2.1.4