0% found this document useful (0 votes)
320 views

Debugging The Linux Kernel With GDB

GDB can be used to debug the Linux kernel through various targets like KGDB, QEMU virtual machines, and JTAG interfaces. Kernel awareness extensions add features to GDB like listing all kernel threads, showing loaded modules, and commands to retrieve kernel data. Improving free and open source debugging tools will help more developers effectively debug kernel issues.

Uploaded by

tedy58
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
320 views

Debugging The Linux Kernel With GDB

GDB can be used to debug the Linux kernel through various targets like KGDB, QEMU virtual machines, and JTAG interfaces. Kernel awareness extensions add features to GDB like listing all kernel threads, showing loaded modules, and commands to retrieve kernel data. Improving free and open source debugging tools will help more developers effectively debug kernel issues.

Uploaded by

tedy58
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

Debugging the Linux Kernel with GDB

Kieran Bingham
Debugging the Linux Kernel with GDB
● Many of us need to debug the Linux kernel
● Proprietary tools like Trace32 and DS-5 are $$$
● Open source debuggers like GDB lack ‘kernel awareness’ features
found in proprietary tools

● What exists today


● How you can use it to get data
● How can we make it better
{They, we} wouldn’t … would {they, we} ?
Linus (~2000)
I don't like debuggers. Never
have, probably never will. I use
gdb all the time, but I tend to
use it not as a debugger, but as You can use a kernel debugger if you
a disassembler on steroids that want to, and I won't give you the cold
you can program. shoulder because you have "sullied"
yourself. But I'm not going to help you
use one, and I would frankly prefer
people not to use kernel debuggers that
much.

http://lwn.net/2000/0914/a/lt-debugger.php3
Why?

There is always code


to debug.
We don’t always write
it ourselves.
But we do have to fix it
How can we improve free tools

● Both LLDB and GDB have extension capabilities

● Jan Kizka has led the way, adding Kernel support for GDB

● OpenOCD provides free JTAG connectivity

● Automated testing needed


Coming Up

● Target options
○ KGDB
○ QEmu/KVM/UML
○ JTAG
○ Core Dumps
● Linux Awareness
○ Thread Awareness
○ Module Support
○ Data retrieval
○ Extending with Python
● Q+A
Targets for debugging Linux with GDB

● GDB client using the gdbremote protocol


a. Connection to a KGDB stub in a running kernel
b. Connect to a QEmu stub running a virtual kernel environment

c. To a gdbremote compliant JTAG probe, such as OpenOCD

● GDB session on host


a. Core Dump file
b. UML Kernel
Core Dumps

KGDB JTAG

Good Better

Qemu
Targets: KGDB with GDB
● Debug stub in the kernel compliant with gdbremote protocol
○ Enable with CONFIG_KGDB

+ Already supported on many platforms


+ All kernel threads enumerated in GDB (via gdbremote)

- Requires cooperation between debugger and kernel stub


- Less suitable for serious crashes
- Isn’t enabled on production systems
- Requires enough support for serial or ethernet

Host Gdbremote Target


serial/ethernet Linux
GDB KGDB
Targets: QEmu
+ Qemu is open source and has gdbremote stub
+ No ‘real’ hardware required
+ Good for testing generic kernel code on many architectures
+ Good environment for developing Kernel Awareness extensions

- Unlikely to be useful for SoC or board related issues


Development Host

Qemu

GDB Client GDB Stub Server

Linux Kernel
Targets : Qemu (Example)
qemu-system-arm -kernel ./zImage -dtb ./vexpress-v2p-ca15-tc1.dtb -M vexpress-a15 -smp 2 -m 1024 -append 'root=/dev/nfs nfsroot=10.0.2.2:/opt/root/armv7/,tcp,v3 rw
ip=dhcp mem=1024M raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0' -nographic -gdb tcp::32770
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.6.0-rc1 (kbingham@CookieMonster) (gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu1) ) #13 SMP Thu Mar 31 10:33:19 BST 2016
[ 0.000000] CPU: ARMv7 Processor [412fc0f1] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[ 0.000000] Machine model: V2P-CA15
[ ….. ]
[ 3.989042] IP-Config: Got DHCP answer from 10.0.2.2, my address is 10.0.2.15
[ 3.991451] IP-Config: Complete:
[ 3.991672] device=eth0, hwaddr=52:54:00:12:34:56, ipaddr=10.0.2.15, mask=255.255.255.0, gw=10.0.2.2
[ 3.991900] host=10.0.2.15, domain=, nis-domain=(none)
[ 3.992039] bootserver=10.0.2.2, rootserver=10.0.2.2, rootpath= nameserver0=10.0.2.3

arm-linux-gdb ./linux/vmlinux -iex 'add-auto-load-safe-path ./linux' -ex 'target remote localhost:32770'


Remote debugging using localhost:32770
cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
74 ret lr
(gdb) info threads
Id Target Id Frame
*1 Thread 1 (CPU#0 [halted ]) cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
2 Thread 2 (CPU#1 [halted ]) cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
(gdb) bt
#0 cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
#1 0xc0308728 in arch_cpu_idle () at /home/lkd/sources/linux/arch/arm/kernel/process.c:72
#2 0xc0376b28 in cpuidle_idle_call () at /home/lkd/sources/linux/kernel/sched/idle.c:151
#3 cpu_idle_loop () at /home/lkd/sources/linux/kernel/sched/idle.c:242
#4 cpu_startup_entry (state=<optimized out>) at /home/lkd/sources/linux/kernel/sched/idle.c:291
#5 0xc0ae8a30 in rest_init () at /home/lkd/sources/linux/init/main.c:408
#6 0xc0f00c5c in start_kernel () at /home/lkd/sources/linux/init/main.c:661
Targets : Qemu (Example)
qemu-system-arm -kernel ./zImage -dtb ./vexpress-v2p-ca15-tc1.dtb -M vexpress-a15 -smp 2 -m 1024 -append 'root=/dev/nfs nfsroot=10.0.2.2:/opt/root/armv7/,tcp,v3 rw
ip=dhcp mem=1024M raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0' -nographic -gdb tcp::32770
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.6.0-rc1 (kbingham@CookieMonster) (gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu1) ) #13 SMP Thu Mar 31 10:33:19 BST 2016
[ 0.000000] CPU: ARMv7 Processor [412fc0f1] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[ 0.000000] Machine model: V2P-CA15
[ ….. ]
[ 3.989042] IP-Config: Got DHCP answer from 10.0.2.2, my address is 10.0.2.15
[ 3.991451] IP-Config: Complete:
[ 3.991672] device=eth0, hwaddr=52:54:00:12:34:56, ipaddr=10.0.2.15, mask=255.255.255.0, gw=10.0.2.2
[ QEmu is a user
3.991900] process
host=10.0.2.15, trying
domain=, to mount NFS on ports above 1024
nis-domain=(none)
[ 3.992039] bootserver=10.0.2.2, rootserver=10.0.2.2, rootpath= nameserver0=10.0.2.3
This isn’t allowed by default, so we need to add the ‘insecure’ option

$ cat./linux/vmlinux
arm-linux-gdb /etc/exports -iex 'add-auto-load-safe-path ./linux' -ex 'target remote localhost:32770'
Remote debugging using localhost:32770
/opt/rootfs
cpu_v7_do_idle *(rw,sync,no_subtree_check,no_root_squash,insecure)
() at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
74 ret lr
(gdb) info threads
Id Target Id Frame
*1 Thread 1 (CPU#0 [halted ]) cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
2 Thread 2 (CPU#1 [halted ]) cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
(gdb) bt
#0 cpu_v7_do_idle () at /home/lkd/sources/linux/arch/arm/mm/proc-v7.S:74
#1 0xc0308728 in arch_cpu_idle () at /home/lkd/sources/linux/arch/arm/kernel/process.c:72
#2 0xc0376b28 in cpuidle_idle_call () at /home/lkd/sources/linux/kernel/sched/idle.c:151
#3 cpu_idle_loop () at /home/lkd/sources/linux/kernel/sched/idle.c:242
#4 cpu_startup_entry (state=<optimized out>) at /home/lkd/sources/linux/kernel/sched/idle.c:291
#5 0xc0ae8a30 in rest_init () at /home/lkd/sources/linux/init/main.c:408
#6 0xc0f00c5c in start_kernel () at /home/lkd/sources/linux/init/main.c:661
Targets: JTAG
+ OpenOCD is open source
+ Supports gdbremote protocol
+ Supports many ARM/MIPS CPUs
+ Supports many FTDI based JTAG
probes http://openocd.org

http://elinux.org/JTAG

Host
OpenOCD Target System

Telnet telnet
JTAG JTAG
GDB Client gdbserver
Targets: Core Dumps
● CONFIG_PROC_KCORE
○ sudo gdb vmlinux /proc/kcore
○ Virtual ELF core file of live kernel
○ No modifications can be made

● CONFIG_PROC_VMCORE
○ /proc/vmcore
○ Used in conjunction with kexec, kdump
and the crash utility from RedHat
○ py-crash, and libkdumpfile support
coming to GDB from SUSE https://en.wikipedia.org/wiki/Kdump_(Linux) @V4711

https://www.suse.com/documentation/sles-12/book_sle_tuning/data/part_tuning_dumps.html
Linux Awareness
● Provide the debugger with additional knowledge of the underlying
operating system to enable a better debugging experience.
○ Where is the Task List?
○ What is in the Kernel Log Buffer?
○ What modules are loaded? Where?

● We split Linux Awareness into three areas


1. Task Awareness
● Ability to report all task_structs as threads in GDB
● Provides selectable GDB threads with context commands

2. Loadable Module Support


● Hooks for automatic symbol resolution when modules are inserted

3. OS Helper Commands
● Interacting with the debugger to obtain useful information
GDB C Extension - Linux Kernel Debugger (LKD)
● Original tools written at ST Micro provide
“Linux Awareness”
● ST-LKD based on GDB 7.6
● Developed for STMC2 JTAG debugger

● Upstream project started by


Peter Griffin, supported by ST
and Linaro
Where to put the ‘awareness’
1. Scripting in GDB (Python/Guile)
2. C extension in GDB
3. Awareness in GDB Stub

Linux Source 1
Python Plugin 2 gdbremote
3
GDB Stub
GDB Client
Kgdb / OpenOCD
Guile Plugin
Kernel Awareness

M
or
Linux Source

e
kn
ux

ow
Lin

led
of

ge
ge

of
led
KGDB

Ta
ow

GDB Client

rg
e
kn

t
e
or
M

QEmu/KVM | JTAG Remote | Core Dump


LKD-C vs LKD-Python
LKD-C LKD-Python
+ Reference code available + Awareness lives in source tree
+ Working now + Generic approach for other OS’s
+ Or languages ….

- Puts Linux specific code into - gdb.Target layer exposes gdb


GDB internal hooks to the outside
- Must be robust!
Thread Awareness : GDB Target Implementation
static struct target_ops * linux_kthread_target (void)
{
struct target_ops *t = XCNEW (struct target_ops);

t->to_shortname = "linux-kthreads";
t->to_longname = "linux kernel-level threads";
t->to_doc = "Linux kernel-level threads"; LKD-C
t->to_close = linux_kthread_close;
t->to_mourn_inferior = linux_kthread_mourn_inferior;
t->to_fetch_registers = linux_kthread_fetch_registers;
t->to_store_registers = linux_kthread_store_registers;
t->to_wait = linux_kthread_wait;
t->to_resume = linux_kthread_resume;
t->to_thread_alive = linux_kthread_thread_alive;
t->to_update_thread_list = linux_kthread_update_thread_list;
t->to_extra_thread_info = linux_kthread_extra_thread_info;
t->to_pid_to_str = linux_kthread_pid_to_str;
t->to_stratum = thread_stratum;
t->to_magic = OPS_MAGIC;

return t;
}
Task Awareness
qemu-system-arm -kernel ./zImage -dtb ./vexpress-v2p-ca15-tc1.dtb -M vexpress-a15 -smp 2 -m 1024 -append 'root=/dev/nfs nfsroot=10.0.2.2:/opt/root/armv7/,tcp,v3 rw
ip=dhcp mem=1024M raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0' -nographic -gdb tcp::32770
[ 0.000000] Booting Linux on physical CPU 0x0
[ 0.000000] Linux version 4.6.0-rc1 (kbingham@CookieMonster) (gcc version 5.2.1 20151010 (Ubuntu 5.2.1-22ubuntu1) ) #13 SMP Thu Mar 31 10:33:19 BST 2016
[ 0.000000] CPU: ARMv7 Processor [412fc0f1] revision 1 (ARMv7), cr=10c5387d
[ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, PIPT instruction cache
[ 0.000000] Machine model: V2P-CA15
[ ….. ]
threads now
appear in the
lkd/bin/arm-linux-gdb ./linux/vmlinux -iex 'add-auto-load-safe-path ./linux' -ex 'target remote localhost:32770'
Remote debugging using localhost:32770 inferior
(gdb) info threads
Id Target Id Frame
*1 [swapper/0] (TGID:0 <C0>) cpu_v7_do_idle () at ../linux/arch/arm/mm/proc-v7.S:74
2 [swapper/1] (TGID:0 <C1>) cpu_v7_do_idle () at ../linux/arch/arm/mm/proc-v7.S:74
3 init (TGID:1) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
4 [kthreadd] (TGID:2) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
5 [ksoftirqd/0] (TGID:3) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
6 [kworker/u4:0] (TGID:6) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
7 [rcu_sched] (TGID:7) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
8 [rcu_bh] (TGID:8) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
9 [migration/0] (TGID:9) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
10 [watchdog/0] (TGID:10) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
11 [cpuhp/0] (TGID:11) context_switch (next=<optimized out>, prev=<optimized out>, rq=<optimized out>) at ../linux/kernel/sched/core.c:2734
[...]
Extending GDB with Python

● Commands
● Functions
● Pretty Printing objects
● Frame Filters / Unwinders
● Breakpoints
● … and more ...

https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html
Thread awareness in Python
def to_update_thread_list(self):
inferior = gdb.selected_inferior() LKD-Python
threads = inferior.threads()

for task in tasks.task_lists():


ptid = [inferior.pid, int(task['pid']), 0] # (pid, lwp, tid)

if ptid not in threads:


thread = inferior.new_thread(ptid, task)
thread.name = task['comm'].string()
# Provide thread registers for backtrace
self.setup_threads(thread, task)
Module Symbol support

(gdb) lx-symbols /opt/rootfs/armv7/lib/modules/4.6.0-rc1/


loading vmlinux
(gdb) c
Continuing.
[email protected]:~# depmod -a
[ 63.643135] random: nonblocking pool is initialized
[email protected]:~# modprobe helloworld
WARNING: All config files need .conf: /etc/modprobe.
d/invalid, it will be ignored in a future release.
scanning for modules in /opt/root/armv7/lib/modules/4.6.0-
rc1/
scanning for modules in /home/lkd/targets/qemu-arm
loading @0xbf000000: ../lib/modules/4.6.0-
rc1/extra/helloworld.ko
[ 73.866004] <1>Hello World 0 !
[ 73.893862] Wow... kernel level thread saying hello :) : 0
[ 73.924062] Wow... kernel level thread saying hello :) : 1
[ 73.952099] Wow... kernel level thread saying hello :) : 2
Linux GDB extensions in v4.6-rc1
(gdb) apropos lx
function lx_current -- Return current task
function lx_module -- Find module by name and return the module variable
function lx_per_cpu -- Return per-cpu variable
function lx_task_by_pid -- Find Linux task by PID and return the task_struct variable
function lx_thread_info -- Calculate Linux thread_info from task variable
lx-cmdline -- Report the Linux Commandline used in the current kernel
lx-dmesg -- Print Linux kernel log buffer
lx-list-check -- Verify a list consistency
lx-lsmod -- List currently loaded modules
lx-ps -- Dump Linux tasks
lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
lx-version -- Report the Linux Version of the current kernel
Extending GDB with Python
gdb.Command : lx-cmdline
class LxCmdLine(gdb.Command):
""" Report the Linux Commandline used in the current kernel.
Equivalent to cat /proc/cmdline on a running target"""

def __init__(self):
super(LxCmdLine, self).__init__("lx-cmdline", gdb.COMMAND_DATA)

def invoke(self, arg, from_tty):


gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n")

LxCmdLine()
Extending GDB with Python
gdb.Command : lx-cmdline
class LxCmdLine(gdb.Command):
""" Report the Linux Commandline used in the current kernel.
(gdb) lx-cmdline
Equivalent to cat /proc/cmdline on a running target"""
root=/dev/nfs nfsroot=10.0.2.2:/opt/root/armv7/,tcp,v3 rw ip=dhcp mem=1024M
raid=noautodetect rootwait console=ttyAMA0,38400n8 devtmpfs.mount=0
def __init__(self):
super(LxCmdLine, self).__init__("lx-cmdline", gdb.COMMAND_DATA)
(gdb) help lx-cmdline
Report the Linux Commandline used in the current kernel.
Equivalent to catarg,
def invoke(self, /proc/cmdline
from_tty): on a running target
gdb.write(gdb.parse_and_eval("saved_command_line").string() + "\n")

LxCmdLine()
Extending GDB with Python
gdb.Function : lx_task_by_pid
class LxTaskByPidFunc(gdb.Function):
"""Find Linux task by PID and return the task_struct variable.

$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
return that task_struct variable which PID matches."""

def __init__(self):
super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")

def invoke(self, pid):


task = get_task_by_pid(pid)
if task:
return task.dereference()
else:
raise gdb.GdbError("No task of PID " + str(pid))

LxTaskByPidFunc()
Extending GDB with Python
gdb.Function : lx_task_by_pid
class LxTaskByPidFunc(gdb.Function):
"""Find Linux task by PID and return the task_struct variable.

$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and
return that task_struct variable which PID matches."""
(gdb) lx-ps
0xeeea5500 1163 lircd
def __init__(self): ## Output trimmed ….
super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")
(gdb) set $task = $lx_task_by_pid(1163)
(gdb) print $task.comm
def invoke(self, pid):
task = get_task_by_pid(pid)
$5 = "lircd\000" if task:
(gdb) print $task.return <tab task.dereference()
completion available>
else:
raise gdb.GdbError("No task of PID " + str(pid))

LxTaskByPidFunc()
Extending GDB with Python
gdb.Function : lx_radix_tree_lookup (not in ML)
(gdb)class
print LxRadixTree(gdb.Function):
irq_desc_tree
""" Lookup and return a node from a RadixTree.
$1 = {
$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index.
height = 1,
If index is omitted, the root node is dereferenced and returned."""
gfp_mask = 37748928,
def __init__(self):
rnode = 0xee000001 super(LxRadixTree, self).__init__("lx_radix_tree_lookup")
}
def invoke(self, root, index=0):
(gdb) print *irq_desc_tree.rnode
result = lookup(root, index)
$2 = { if result is None:
raise gdb.GdbError("No entry in tree at index {}".format(index))
path = 855638016,
count = 0, return result

…. LxRadixTree()
slots = {0xc0ee8030, 0x80ee8030, 0x40ee8031, 0xee8032, 0xc0ee8033, …...
Extending GDB with Python
gdb.Function : lx_radix_tree_lookup (not in ML)
class LxRadixTree(gdb.Function):
""" Lookup and return a node from a RadixTree.

$lx_radix_tree_lookup(root_node [, index]): Return the node at the given index.


If index is omitted, the root node is dereferenced and returned."""

def __init__(self):
super(LxRadixTree, self).__init__("lx_radix_tree_lookup")

def invoke(self, root, index=0):


result = lookup(root, index)
if result is None:
raise gdb.GdbError("No entry in tree at index {}".format(index))

return result

LxRadixTree()
[PATCHv4 10/12] scripts/gdb: Add a Radix Tree Parser
https://lkml.org/lkml/2016/3/30/277
Extending GDB with Python
gdb.Function : lx_radix_tree_lookup (not in ML)
class LxRadixTree(gdb.Function):
""" Lookup
(gdb) print and return
((struct a node from a RadixTree.
irq_desc)$lx_radix_tree_lookup(irq_desc_tree, 18)).irq_data
$3 = $lx_radix_tree_lookup(root_node
{ [, index]): Return the node at the given index.
maskIf index
= 0,is omitted, the root node is dereferenced and returned."""
irq = 18,
def __init__(self):
hwirq = 27, super(LxRadixTree, self).__init__("lx_radix_tree_lookup")
common = 0xee803d80,
def invoke(self, root, index=0):
result = lookup(root, index)
chip = 0xc100285c <gic_data>,
if result is None:
domain = 0xee808000, raise gdb.GdbError("No entry in tree at index {}".format(index))
parent_data = return 0x0,result
chip_data = 0xc100285c <gic_data>
LxRadixTree()
}
Extending GDB with Python : Accessing data
● GDB provides accessors to read memory
def module_list():
modules = gdb.parse_and_eval("modules")
entry = modules['next']
end_of_list = modules.address

● Reading structures is ‘easy’


for vfs in lists.list_for_each_entry(namespace['list'],mount_ptr_type, "mnt_list"):
devname = vfs['mnt_devname'].string()
superblock = vfs['mnt']['mnt_sb']
fstype = superblock['s_type']['name'].string()
s_flags = int(superblock['s_flags'])
m_flags = int(vfs['mnt']['mnt_flags'])

● Complicated data structures can be programmed


Python Extension Summary
● Easy to write your own commands / plugins to GDB
● Docstring as Documentation
● Accessing data in Python is easy
○ Structures organised as python dictionaries
○ Pointers automatically dereferenced
What’s Next
● Automated regression testing
○ LAVA / KernelCI ...

● Continue upstream push of thread awareness


○ C / Python / Javascript

And then ?
● IDE integration
● Userspace debug extensions?
● Page table walks?
● The world ...
Summary

Targets Kernel Awareness


● KGDB ● Thread Awareness
○ In kernel debugging ○ In Progress!
● QEmu / KVM / UML ● Module support
○ Virtualized environments ○ Mostly there
● JTAG ● Data Retrieval
○ Real Hardware ○ Commands available
● Core Dumps ● Oysters or Pythons?
○ Real problems ○ The world is your ...
Some references / Credits
● Linaro
○ http://www.linaro.org
● O’Rly Images
○ Buy the T-Shirts @ https://threddit.com/ThePracticalDev
● GDB Python API Documentation
○ https://sourceware.org/gdb/onlinedocs/gdb/Python-API.html
● Me
○ http://www.kieranbingham.co.uk

Slides should be available on ELC website, or from my Blog URL


Code/GIT URL’s
● [PATCHv4 00/12] gdb/scripts: Linux awareness debug commands
○ https://lkml.org/lkml/2016/3/30/269
● Linux
○ https://git.linaro.org/people/kieran.bingham/linux.git
■ Tag: gdb-scripts-v4 - Latest submission
■ Branch: gdb-scripts - All work including experimental linux-awareness.py
● Binutils-GDB :
○ https://git.linaro.org/people/kieran.bingham/binutils-gdb.git/
■ Branch: lkd-thread-aware-c - Working version of thread awareness
■ Branch: linux-kthreads - Work in progress - C implementation for upstream
■ Branch: lkd-python - Experimental - Python gdb.Target
● Qemu Quickstart (to try thread awareness, using lkd-thread-aware-c)
○ git clone https://git.linaro.org/people/kieran.bingham/qemu-kernel.git
○ Make # builds kernel, and binutils-gdb
○ Terminal 1: make qemu-run | Terminal 2: make qemu-gdb
Q+A?

You might also like