Debugging in linux kernel

Debugging kernel and modules via gdbВ¶

The kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware interfaces allow to debug the Linux kernel and its modules during runtime using gdb. Gdb comes with a powerful scripting interface for python. The kernel provides a collection of helper scripts that can simplify typical kernel debugging steps. This is a short tutorial about how to enable and use them. It focuses on QEMU/KVM virtual machines as target, but the examples can be transferred to the other gdb stubs as well.

RequirementsВ¶

  • gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true for distributions)

SetupВ¶

Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and www.qemu.org for more details). For cross-development, http://landley.net/aboriginal/bin keeps a pool of machine images and toolchains that can be helpful to start from.

Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports CONFIG_FRAME_POINTER, keep it enabled.

Install that kernel on the guest. Alternatively, QEMU allows to boot the kernel directly using -kernel, -append, -initrd command line switches. This is generally only useful if you do not depend on modules. See QEMU documentation for more details on this mode.

Enable the gdb stub of QEMU/KVM, either

  • at VM startup time by appending “-s” to the QEMU command line
  • during runtime by issuing “gdbserver” from the QEMU monitor console

Start gdb: gdb vmlinux

Note: Some distros may restrict auto-loading of gdb scripts to known safe directories. In case gdb reports to refuse loading vmlinux-gdb.py, add:

/.gdbinit. See gdb help for more details.

Attach to the booted guest:

Examples of using the Linux-provided gdb helpersВ¶

Load module (and main kernel) symbols:

Set a breakpoint on some not yet loaded module function, e.g.:

Continue the target:

Load the module on the target and watch the symbols being loaded as well as the breakpoint hit:

Dump the log buffer of the target kernel:

Examine fields of the current task struct:

Make use of the per-cpu function for the current or a specified CPU:

Dig into hrtimers using the container_of helper:

List of commands and functionsВ¶

The number of commands and convenience functions may evolve over the time, this is just a snapshot of the initial version:

Detailed help can be obtained via “help ” for commands and “help function ” for convenience functions.

© Copyright The kernel development community.

Источник

Dynamic debugВ¶

IntroductionВ¶

This document describes how to use the dynamic debug (dyndbg) feature.

Dynamic debug is designed to allow you to dynamically enable/disable kernel code to obtain additional kernel information. Currently, if CONFIG_DYNAMIC_DEBUG is set, then all pr_debug() / dev_dbg() and print_hex_dump_debug() / print_hex_dump_bytes() calls can be dynamically enabled per-callsite.

If you do not want to enable dynamic debug globally (i.e. in some embedded system), you may set CONFIG_DYNAMIC_DEBUG_CORE as basic support of dynamic debug and add ccflags := -DDYNAMIC_DEBUG_MODULE into the Makefile of any modules which you’d like to dynamically debug later.

If CONFIG_DYNAMIC_DEBUG is not set, print_hex_dump_debug() is just shortcut for print_hex_dump(KERN_DEBUG) .

For print_hex_dump_debug() / print_hex_dump_bytes() , format string is its prefix_str argument, if it is constant string; or hexdump in case prefix_str is built dynamically.

Dynamic debug has even more useful features:

Simple query language allows turning on and off debugging statements by matching any combination of 0 or 1 of:

line number (including ranges of line numbers)

Provides a debugfs control file: /dynamic_debug/control which can be read to display the complete list of known debug statements, to help guide you

Controlling dynamic debug BehaviourВ¶

The behaviour of pr_debug() / dev_dbg() are controlled via writing to a control file in the ‘debugfs’ filesystem. Thus, you must first mount the debugfs filesystem, in order to make use of this feature. Subsequently, we refer to the control file as: /dynamic_debug/control . For example, if you want to enable printing from source file svcsock.c , line 1603 you simply do:

If you make a mistake with the syntax, the write will fail thus:

Note, for systems without ‘debugfs’ enabled, the control file can be found in /proc/dynamic_debug/control .

Viewing Dynamic Debug BehaviourВ¶

You can view the currently configured behaviour of all the debug statements via:

You can also apply standard Unix text manipulation filters to this data, e.g.:

The third column shows the currently enabled flags for each debug statement callsite (see below for definitions of the flags). The default value, with no flags enabled, is =_ . So you can view all the debug statement callsites with any non-default flags:

Читайте также:  Установить adblock для windows 10

Command Language ReferenceВ¶

At the lexical level, a command comprises a sequence of words separated by spaces or tabs. So these are all equivalent:

Command submissions are bounded by a write() system call. Multiple commands can be written together, separated by ; or \n :

If your query set is big, you can batch them too:

Another way is to use wildcards. The match rule supports * (matches zero or more characters) and ? (matches exactly one character). For example, you can match all usb drivers:

At the syntactical level, a command comprises a sequence of match specifications, followed by a flags change specification:

The match-spec’s are used to choose a subset of the known pr_debug() callsites to which to apply the flags-spec. Think of them as a query with implicit ANDs between each pair. Note that an empty list of match-specs will select all debug statement callsites.

A match specification comprises a keyword, which controls the attribute of the callsite to be compared, and a value to compare against. Possible keywords are::

line-range cannot contain space, e.g. “1-30” is valid range but “1 — 30” is not.

The meanings of each keyword are:

The given string is compared against the function name of each callsite. Example:

The given string is compared against either the src-root relative pathname, or the basename of the source file of each callsite. Examples:

The given string is compared against the module name of each callsite. The module name is the string as seen in lsmod , i.e. without the directory or the .ko suffix and with — changed to _ . Examples:

The given string is searched for in the dynamic debug format string. Note that the string does not need to match the entire format, only some part. Whitespace and other special characters can be escaped using C octal character escape \ooo notation, e.g. the space character is \040 . Alternatively, the string can be enclosed in double quote characters ( » ) or single quote characters ( ‘ ). Examples:

The given line number or range of line numbers is compared against the line number of each pr_debug() callsite. A single line number matches the callsite line number exactly. A range of line numbers matches any callsite between the first and last line number inclusive. An empty first number means the first line in the file, an empty last line number means the last line number in the file. Examples:

The flags specification comprises a change operation followed by one or more flag characters. The change operation is one of the characters:

For print_hex_dump_debug() and print_hex_dump_bytes() , only p flag have meaning, other flags ignored.

For display, the flags are preceded by = (mnemonic: what the flags are currently equal to).

Note the regexp ^[-+=][flmpt_]+$ matches a flags specification. To clear all flags at once, use =_ or -flmpt .

Debug messages during Boot ProcessВ¶

To activate debug messages for core code and built-in modules during the boot process, even before userspace and debugfs exists, use dyndbg=»QUERY» , module.dyndbg=»QUERY» , or ddebug_query=»QUERY» ( ddebug_query is obsoleted by dyndbg , and deprecated). QUERY follows the syntax described above, but must not exceed 1023 characters. Your bootloader may impose lower limits.

These dyndbg params are processed just after the ddebug tables are processed, as part of the early_initcall. Thus you can enable debug messages in all code run after this early_initcall via this boot parameter.

On an x86 system for example ACPI enablement is a subsys_initcall and:

will show early Embedded Controller transactions during ACPI setup if your machine (typically a laptop) has an Embedded Controller. PCI (or other devices) initialization also is a hot candidate for using this boot parameter for debugging purposes.

If foo module is not built-in, foo.dyndbg will still be processed at boot time, without effect, but will be reprocessed when module is loaded later. ddebug_query= and bare dyndbg= are only processed at boot.

Debug Messages at Module Initialization TimeВ¶

When modprobe foo is called, modprobe scans /proc/cmdline for foo.params , strips foo. , and passes them to the kernel along with params given in modprobe args or /etc/modprob.d/*.conf files, in the following order:

parameters given via /etc/modprobe.d/*.conf :

foo.dyndbg as given in boot args, foo. is stripped and passed:

args to modprobe:

These dyndbg queries are applied in order, with last having final say. This allows boot args to override or modify those from /etc/modprobe.d (sensible, since 1 is system wide, 2 is kernel or boot specific), and modprobe args to override both.

In the foo.dyndbg=»QUERY» form, the query must exclude module foo . foo is extracted from the param-name, and applied to each query in QUERY , and only 1 match-spec of each type is allowed.

The dyndbg option is a “fake” module parameter, which means:

modules do not need to define it explicitly

every module gets it tacitly, whether they use pr_debug or not

Читайте также:  Sqlite studio linux install

it doesn’t appear in /sys/module/$module/parameters/ To see it, grep the control file, or inspect /proc/cmdline.

For CONFIG_DYNAMIC_DEBUG kernels, any settings given at boot-time (or enabled by -DDEBUG flag during compilation) can be disabled later via the debugfs interface if the debug messages are no longer needed:

Источник

Debugging kernel and modules via gdbВ¶

The kernel debugger kgdb, hypervisors like QEMU or JTAG-based hardware interfaces allow to debug the Linux kernel and its modules during runtime using gdb. Gdb comes with a powerful scripting interface for python. The kernel provides a collection of helper scripts that can simplify typical kernel debugging steps. This is a short tutorial about how to enable and use them. It focuses on QEMU/KVM virtual machines as target, but the examples can be transferred to the other gdb stubs as well.

RequirementsВ¶

gdb 7.2+ (recommended: 7.4+) with python support enabled (typically true for distributions)

SetupВ¶

Create a virtual Linux machine for QEMU/KVM (see www.linux-kvm.org and www.qemu.org for more details). For cross-development, https://landley.net/aboriginal/bin keeps a pool of machine images and toolchains that can be helpful to start from.

Build the kernel with CONFIG_GDB_SCRIPTS enabled, but leave CONFIG_DEBUG_INFO_REDUCED off. If your architecture supports CONFIG_FRAME_POINTER, keep it enabled.

Install that kernel on the guest, turn off KASLR if necessary by adding “nokaslr” to the kernel command line. Alternatively, QEMU allows to boot the kernel directly using -kernel, -append, -initrd command line switches. This is generally only useful if you do not depend on modules. See QEMU documentation for more details on this mode. In this case, you should build the kernel with CONFIG_RANDOMIZE_BASE disabled if the architecture supports KASLR.

Enable the gdb stub of QEMU/KVM, either

at VM startup time by appending “-s” to the QEMU command line

during runtime by issuing “gdbserver” from the QEMU monitor console

Start gdb: gdb vmlinux

Note: Some distros may restrict auto-loading of gdb scripts to known safe directories. In case gdb reports to refuse loading vmlinux-gdb.py, add:

/.gdbinit. See gdb help for more details.

Attach to the booted guest:

Examples of using the Linux-provided gdb helpersВ¶

Load module (and main kernel) symbols:

Set a breakpoint on some not yet loaded module function, e.g.:

Continue the target:

Load the module on the target and watch the symbols being loaded as well as the breakpoint hit:

Dump the log buffer of the target kernel:

Examine fields of the current task struct(supported by x86 and arm64 only):

Make use of the per-cpu function for the current or a specified CPU:

Dig into hrtimers using the container_of helper:

List of commands and functionsВ¶

The number of commands and convenience functions may evolve over the time, this is just a snapshot of the initial version:

Detailed help can be obtained via “help ” for commands and “help function ” for convenience functions.

© Copyright The kernel development community.

Источник

Dynamic debugВ¶

IntroductionВ¶

This document describes how to use the dynamic debug (dyndbg) feature.

Dynamic debug is designed to allow you to dynamically enable/disable kernel code to obtain additional kernel information. Currently, if CONFIG_DYNAMIC_DEBUG is set, then all pr_debug() / dev_dbg() and print_hex_dump_debug() / print_hex_dump_bytes() calls can be dynamically enabled per-callsite.

If CONFIG_DYNAMIC_DEBUG is not set, print_hex_dump_debug() is just shortcut for print_hex_dump(KERN_DEBUG) .

For print_hex_dump_debug() / print_hex_dump_bytes() , format string is its prefix_str argument, if it is constant string; or hexdump in case prefix_str is build dynamically.

Dynamic debug has even more useful features:

  • Simple query language allows turning on and off debugging statements by matching any combination of 0 or 1 of:
    • source filename
    • function name
    • line number (including ranges of line numbers)
    • module name
    • format string
  • Provides a debugfs control file: /dynamic_debug/control which can be read to display the complete list of known debug statements, to help guide you

Controlling dynamic debug BehaviourВ¶

The behaviour of pr_debug() / dev_dbg() are controlled via writing to a control file in the ‘debugfs’ filesystem. Thus, you must first mount the debugfs filesystem, in order to make use of this feature. Subsequently, we refer to the control file as: /dynamic_debug/control . For example, if you want to enable printing from source file svcsock.c , line 1603 you simply do:

If you make a mistake with the syntax, the write will fail thus:

Viewing Dynamic Debug BehaviourВ¶

You can view the currently configured behaviour of all the debug statements via:

You can also apply standard Unix text manipulation filters to this data, e.g.:

The third column shows the currently enabled flags for each debug statement callsite (see below for definitions of the flags). The default value, with no flags enabled, is =_ . So you can view all the debug statement callsites with any non-default flags:

Command Language ReferenceВ¶

At the lexical level, a command comprises a sequence of words separated by spaces or tabs. So these are all equivalent:

Command submissions are bounded by a write() system call. Multiple commands can be written together, separated by ; or \n :

Читайте также:  Назначить статический ip linux

If your query set is big, you can batch them too:

A another way is to use wildcard. The match rule support * (matches zero or more characters) and ? (matches exactly one character).For example, you can match all usb drivers:

At the syntactical level, a command comprises a sequence of match specifications, followed by a flags change specification:

The match-spec’s are used to choose a subset of the known pr_debug() callsites to which to apply the flags-spec. Think of them as a query with implicit ANDs between each pair. Note that an empty list of match-specs will select all debug statement callsites.

A match specification comprises a keyword, which controls the attribute of the callsite to be compared, and a value to compare against. Possible keywords are::

line-range cannot contain space, e.g. “1-30” is valid range but “1 — 30” is not.

The meanings of each keyword are:

The given string is compared against the function name of each callsite. Example:

The given string is compared against either the full pathname, the src-root relative pathname, or the basename of the source file of each callsite. Examples:

The given string is compared against the module name of each callsite. The module name is the string as seen in lsmod , i.e. without the directory or the .ko suffix and with — changed to _ . Examples:

The given string is searched for in the dynamic debug format string. Note that the string does not need to match the entire format, only some part. Whitespace and other special characters can be escaped using C octal character escape \ooo notation, e.g. the space character is \040 . Alternatively, the string can be enclosed in double quote characters ( » ) or single quote characters ( ‘ ). Examples:

The given line number or range of line numbers is compared against the line number of each pr_debug() callsite. A single line number matches the callsite line number exactly. A range of line numbers matches any callsite between the first and last line number inclusive. An empty first number means the first line in the file, an empty line number means the last number in the file. Examples:

The flags specification comprises a change operation followed by one or more flag characters. The change operation is one of the characters:

For print_hex_dump_debug() and print_hex_dump_bytes() , only p flag have meaning, other flags ignored.

For display, the flags are preceded by = (mnemonic: what the flags are currently equal to).

Note the regexp ^[-+=][flmpt_]+$ matches a flags specification. To clear all flags at once, use =_ or -flmpt .

Debug messages during Boot ProcessВ¶

To activate debug messages for core code and built-in modules during the boot process, even before userspace and debugfs exists, use dyndbg=»QUERY» , module.dyndbg=»QUERY» , or ddebug_query=»QUERY» ( ddebug_query is obsoleted by dyndbg , and deprecated). QUERY follows the syntax described above, but must not exceed 1023 characters. Your bootloader may impose lower limits.

These dyndbg params are processed just after the ddebug tables are processed, as part of the arch_initcall. Thus you can enable debug messages in all code run after this arch_initcall via this boot parameter.

On an x86 system for example ACPI enablement is a subsys_initcall and:

will show early Embedded Controller transactions during ACPI setup if your machine (typically a laptop) has an Embedded Controller. PCI (or other devices) initialization also is a hot candidate for using this boot parameter for debugging purposes.

If foo module is not built-in, foo.dyndbg will still be processed at boot time, without effect, but will be reprocessed when module is loaded later. dyndbg_query= and bare dyndbg= are only processed at boot.

Debug Messages at Module Initialization TimeВ¶

When modprobe foo is called, modprobe scans /proc/cmdline for foo.params , strips foo. , and passes them to the kernel along with params given in modprobe args or /etc/modprob.d/*.conf files, in the following order:

parameters given via /etc/modprobe.d/*.conf :

foo.dyndbg as given in boot args, foo. is stripped and passed:

args to modprobe:

These dyndbg queries are applied in order, with last having final say. This allows boot args to override or modify those from /etc/modprobe.d (sensible, since 1 is system wide, 2 is kernel or boot specific), and modprobe args to override both.

In the foo.dyndbg=»QUERY» form, the query must exclude module foo . foo is extracted from the param-name, and applied to each query in QUERY , and only 1 match-spec of each type is allowed.

The dyndbg option is a “fake” module parameter, which means:

  • modules do not need to define it explicitly
  • every module gets it tacitly, whether they use pr_debug or not
  • it doesn’t appear in /sys/module/$module/parameters/ To see it, grep the control file, or inspect /proc/cmdline.

For CONFIG_DYNAMIC_DEBUG kernels, any settings given at boot-time (or enabled by -DDEBUG flag during compilation) can be disabled later via the sysfs interface if the debug messages are no longer needed:

Источник

Оцените статью