KDB 介绍和使用

/ 2评 / 0

reship from http://elinux.org/KDB

Contents

Introduction and basic resources

Here is some information about KDB - the in-kernel debugger for the Linux kernel.

The KDB and KGDB official wiki: https://kgdb.wiki.kernel.org/ (this only has 2 pages?)

Jason Wessel is the current KDB maintainer. Here is a presentation from him at LinuxCon 2010 (August 2010):
http://kernel.org/pub/linux/kernel/people/jwessel/dbg_webinar/State_Of_kernel_debugging_LinuxCon2010.pdf

Here are some videos showing use of KDB and KGDB:

Documentation, up-to-date as of 2010, for KDB and KGDB is at: http://kernel.org/pub/linux/kernel/people/jwessel/kdb/

Older Information

See http://www.ibm.com/developerworks/linux/library/l-kdbug/ for a tutorial for the 2.4.20 kernel (from June 2003)

Here's an article from 2002 on KDB vs. KGDB: http://kerneltrap.org/node/112
It has a good discussion excerpt between Andrew Morton and Keith Owens about the relative merits of KDB versus KGDB.

General Information

Kernel Versions supported

kgdb was added to the mainline Linux kernel in version 2.6.26.

kdb support was added to the mainline Linux kernel in version 2.6.35.

Before those versions, kgdb and kdb were available as patches which could be
applied to the Linux kernel source.

Kernel configuration

The following descriptions are for a 2.6.35 kernel, using KDB over a serial line between host and target:

All these options on are the "Kernel Hacking" menu.

In order to support KDB, "KGDB" support must be turned on first (even if you aren't using kgdb/gdb)

Optional other configuration settings:

Enabling kdb

At runtime

Once the kernel is compiled with kdb support and is running on your target board, you need to
enable it. This can be done on a running system, binding the kdb/kgdb feature to a serial port,
by writing a value into the sys filesystem.

If your machine starts a serial console on ttyS0, you can bind kdb/kgdb to this serial console
by writing the string "ttyS0" to /sys/module/kgdboc/parameters/kgdboc. The kernel will respond
with a message indicating that that driver is registered.

$ echo ttyS0 >/sys/module/kgdboc/parameters/kgdboc
kgdb: Registered I/O driver kgdboc.

At boot time (via kernel command line)

You can enable kdb support in your kernel at boot time by using the 'kgdboc' option on the
kernel command line. Normally, you specify the tty device name, followed by the serial port speed.

kgdboc=ttyS0,115200

Invoking kdb

Once the kernel is running, and the kgdb/kdb is bound to the serial console, you can
invoke the debugger in numerous ways.

First, you can enter the debugger using a Magic SysRq command.

kdb will also be entered automatically if the kernel panics.

Finally, you can set a breakpoint (either hardware or software), such that the debugger is
invoked when the breakpoint condition is met. For a code breakpoint, this means when
the instruction is executed at the breakpoint location, and for a data breakpoint, when the
particular access is made at the breakpoint address.

Invoking with Magic SysRq 'g'

To invoke the debugger using the Magic SysRq command, you use the 'g' command, which
can be issued any of the ways supported by the Magic SysRq feature. This can be done
by 1) typing the key sequence on a connected keyboard, 2) echoing a value to /proc/sysrq-trigger, or
3) sending a break key sequence through the serial console

Examples:

Invocation by panic

When a kernel panic occurs, then something has gone seriously wrong and the kernel automatically enters
kdb. From here you can look at memory, do a traceback, examine registers, and do other operations to
find out more about the state of the system and debug the problem.

Invocation by breakpoint

To enter kdb using a breakpoint, first invoke kdb using the Magic SysRq key (see above), then set a breakpoint.
Then type 'go' to continue execution. When the breakpoint is hit, the debugger shell will appear.

In the example that follows, items in italics are commands typed by a user.
Items following a '$' are commands entered at a shell command (normal
Linux user-space runtime), and items following 'kgdb>' are commands entered
at the kdb interactive shell.

$ echo g >/proc/sysrq-trigger 
SysRq : DEBUG
 
Entering kdb (current=0xdfdff040, pid 71) due to Keyboard Entry
kdb> bp sys_sync+4 
Instruction(i) BP #0 at 0xc00c9f00 (sys_sync+0x4)
   is enabled  addr at 00000000c00c9f00, hardtype=0 installed=0
 
kdb> go 
$ sync 
 
Entering kdb (current=0xdfdaa360, pid 72) due to Breakpoint @ 0xc00c9f00
kdb> bt 
Stack traceback for pid 72
0xdfdaa360       72       71  1    0   R  0xdfdaa560 *sync
[<c0028cb4>] (unwind_backtrace+0x0/0xe4) from [<c0026d50>] (show_stack+0x10/0x14)
[<c0026d50>] (show_stack+0x10/0x14) from [<c0079e78>] (kdb_show_stack+0x58/0x80)
[<c0079e78>] (kdb_show_stack+0x58/0x80) from [<c0079f1c>] (kdb_bt1.clone.0+0x7c/0xcc)
[<c0079f1c>] (kdb_bt1.clone.0+0x7c/0xcc) from [<c007a240>] (kdb_bt+0x2d4/0x338)
[<c007a240>] (kdb_bt+0x2d4/0x338) from [<c0078328>] (kdb_parse+0x4d4/0x5f8)
[<c0078328>] (kdb_parse+0x4d4/0x5f8) from [<c0078a8c>] (kdb_main_loop+0x448/0x6b0)
[<c0078a8c>] (kdb_main_loop+0x448/0x6b0) from [<c007acb4>] (kdb_stub+0x210/0x398)
[<c007acb4>] (kdb_stub+0x210/0x398) from [<c0073280>] (kgdb_handle_exception+0x384/0x574)
[<c0073280>] (kgdb_handle_exception+0x384/0x574) from [<c0028518>] (kgdb_brk_fn+0x18/0x20)
[<c0028518>] (kgdb_brk_fn+0x18/0x20) from [<c0022198>] (do_undefinstr+0x10c/0x1a8)
[<c0022198>] (do_undefinstr+0x10c/0x1a8) from [<c0022b84>] (__und_svc+0x44/0x60)
Exception stack(0xdfe09f58 to 0xdfe09fa0)
9f40:                                                       00000000 bec93e74
9f60: 000437ac 00034738 00000001 bec93e74 00000049 00000024 c00230e8 dfe08000
9f80: 00000000 bec93e54 00000000 dfe09fa0 c0022f40 c00c9f00 80000013 ffffffff
[<c0022b84>] (__und_svc+0x44/0x60) from [<c00c9f00>] (sys_sync+0x4/0x28)
[<c00c9f00>] (sys_sync+0x4/0x28) from [<c0022f40>] (ret_fast_syscall+0x0/0x30)
kdb>

This example shows an invocation of kdb, followed by setting a breakpoint, then
resuming execution with 'go'. Then, at the Linux user-space shell, the 'sync' command
is run to cause the breakpoint to occur. When kdb is entered due to the breakpoint,
then 'bt' is run to get a backtrace from the stack of the current process.

Using gdb to see the kernel source listing

You can use the addresses printed out in kdb, with a host-side gdb session, to see
the source code or assembly instructions around a particular address.

The target address can come from a backtrace or register dump (e.g. instruction pointer).

To load the source for a kernel, start gdb (or the appropriate arch-specific gdb) with the
vmlinux that matches the image running on target.
The kernel should have been compiled with debug symbols (CONFIG_DEBUG_KERNEL=y).
gdb will start, and load the symbol information for the kernel.

Use the following commands to see various bits of information:

KDB environment variables

Here are some environment variables supported by kdb (in 2.6.35):

Unused args (in 2.6.35):

Hints and tips

Command line completion

kdb supports command line completion using the tab key. While typing at the interactive shell, you can press the tab key to get a list of symbols to use as part of the command. If you type the first few letters of a symbol name, then press the tab key, the shell will complete the name for you. If more than one symbol matches
what you have typed, then a list is shown of matching symbols. The number of symbols shown is controlled by
the DTABCOUNT variable.

Defining a set of commands

You can define a set of commands to be run as a group (in sequence), using the 'defcmd' command.
This group essentially becomes a new command which you can run, using the indicated name.

The second two strings after the new command name are the Usage string and the Description string.
These appear in the online help when the 'help' or '?' commands are run.

Here is an example of the definition of a new command:

defcmd dumpcommon "" "Common kdb debugging"
  set BTAPROMPT 0
  set LINES 10000
  -summary
  -cpu
  -ps
  -dmesg 600
  -bt
endefcmd

A leading dash indicates to ignore any errors processing a command.

Executing commands on kdb initialization

In the kernel source, you can place commands in the file 'kdb_cmds'. These commands will be executed
by kdb on it's initialization. By default, a few command sets are declared: 'dumpcommon', 'dumpall', and 'dumpcpu'.

Piping command results through 'grep'

kdb includes a grep-like capability, which provides the ability to filter command results using a pattern. To
use this, type the regular command, and at the end of the line add '| grep <pattern>', where pattern is the pattern to match.

To see online help for this feature, type 'grephelp' at the kdb shell prompt.

The pattern may include a very limited set of metacharacters:

  pattern or ^pattern or pattern$ or ^pattern$

And if there are spaces in the pattern, you may quote it:

  "pat tern" or "^pat tern" or "pat tern$" or "^pat tern$"

Command history

You can access the command history by typing up-arrow and down-arrow, and select a previous command to run.

If you hit <enter> without typing a command, sometimes (when it makes sense) the last command run will be run again. For 'md' commands, the next command will continue at the address where the last command left off.

Feature extension notes (by Tim)

internals

internal functions to retrieve environment variables:

2条回应:“KDB 介绍和使用”

  1. cuic139说道:

    DDD大神,我又来了,嘿嘿,最近kdb进场出现重入然后卡死的情况,不知道您遇到过没

    信息如下:

    kdb: Debugger re-entered on cpu 1, new reason = 1
    Not executing a kdb command
    No longjmp available for recovery
    Cannot recover, allowing event to proceed

    其实就是在kdb()函数里面又panic了,结果在debugger情况下又再次debugger了,

    请教这种情况下该如何处理呢,正常情况下是会出现kdb重入的,不过几率非常小,可是在我这里比如在sys_mkdir函数下了一个断点,然后执行mkdir命令会进入断点,然后go出来就会出现上面的信息,这样就不正常了,您遇到过吗?

    [回复]

    DDD 回复:

    @cuic139 @cuic139

    kdb重入是有可能的,它没有像kprobe一样对一些关键性地方进行保护。
    但是我看你是对sys_mkdir下断点,这个应该不会引起重入的。
    我现在没有环境,很难做判断,等我有环境了,我自己去实验下。:-)

    [回复]

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据