Initial commit: Linux kernel 4.19 for Unplugged OS

This commit is contained in:
ziv committed 2025-10-06 13:52:42 +00:00
commit d30235b04c
80519 files changed
+35800681

No files matched your search

+488
View File
@@ -0,0 +1,488 @@
.. Copyright 2010 Nicolas Palix <npalix@diku.dk>
.. Copyright 2010 Julia Lawall <julia@diku.dk>
.. Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
.. highlight:: none
Coccinelle
==========
Coccinelle is a tool for pattern matching and text transformation that has
many uses in kernel development, including the application of complex,
tree-wide patches and detection of problematic programming patterns.
Getting Coccinelle
-------------------
The semantic patches included in the kernel use features and options
which are provided by Coccinelle version 1.0.0-rc11 and above.
Using earlier versions will fail as the option names used by
the Coccinelle files and coccicheck have been updated.
Coccinelle is available through the package manager
of many distributions, e.g. :
- Debian
- Fedora
- Ubuntu
- OpenSUSE
- Arch Linux
- NetBSD
- FreeBSD
You can get the latest version released from the Coccinelle homepage at
http://coccinelle.lip6.fr/
Once you have it, run the following command::
./configure
make
as a regular user, and install it with::
sudo make install
Supplemental documentation
---------------------------
For supplemental documentation refer to the wiki:
https://bottest.wiki.kernel.org/coccicheck
The wiki documentation always refers to the linux-next version of the script.
Using Coccinelle on the Linux kernel
------------------------------------
A Coccinelle-specific target is defined in the top level
Makefile. This target is named ``coccicheck`` and calls the ``coccicheck``
front-end in the ``scripts`` directory.
Four basic modes are defined: ``patch``, ``report``, ``context``, and
``org``. The mode to use is specified by setting the MODE variable with
``MODE=<mode>``.
- ``patch`` proposes a fix, when possible.
- ``report`` generates a list in the following format:
file:line:column-column: message
- ``context`` highlights lines of interest and their context in a
diff-like style.Lines of interest are indicated with ``-``.
- ``org`` generates a report in the Org mode format of Emacs.
Note that not all semantic patches implement all modes. For easy use
of Coccinelle, the default mode is "report".
Two other modes provide some common combinations of these modes.
- ``chain`` tries the previous modes in the order above until one succeeds.
- ``rep+ctxt`` runs successively the report mode and the context mode.
It should be used with the C option (described later)
which checks the code on a file basis.
Examples
~~~~~~~~
To make a report for every semantic patch, run the following command::
make coccicheck MODE=report
To produce patches, run::
make coccicheck MODE=patch
The coccicheck target applies every semantic patch available in the
sub-directories of ``scripts/coccinelle`` to the entire Linux kernel.
For each semantic patch, a commit message is proposed. It gives a
description of the problem being checked by the semantic patch, and
includes a reference to Coccinelle.
As any static code analyzer, Coccinelle produces false
positives. Thus, reports must be carefully checked, and patches
reviewed.
To enable verbose messages set the V= variable, for example::
make coccicheck MODE=report V=1
Coccinelle parallelization
---------------------------
By default, coccicheck tries to run as parallel as possible. To change
the parallelism, set the J= variable. For example, to run across 4 CPUs::
make coccicheck MODE=report J=4
As of Coccinelle 1.0.2 Coccinelle uses Ocaml parmap for parallelization,
if support for this is detected you will benefit from parmap parallelization.
When parmap is enabled coccicheck will enable dynamic load balancing by using
``--chunksize 1`` argument, this ensures we keep feeding threads with work
one by one, so that we avoid the situation where most work gets done by only
a few threads. With dynamic load balancing, if a thread finishes early we keep
feeding it more work.
When parmap is enabled, if an error occurs in Coccinelle, this error
value is propagated back, the return value of the ``make coccicheck``
captures this return value.
Using Coccinelle with a single semantic patch
---------------------------------------------
The optional make variable COCCI can be used to check a single
semantic patch. In that case, the variable must be initialized with
the name of the semantic patch to apply.
For instance::
make coccicheck COCCI=<my_SP.cocci> MODE=patch
or::
make coccicheck COCCI=<my_SP.cocci> MODE=report
Controlling Which Files are Processed by Coccinelle
---------------------------------------------------
By default the entire kernel source tree is checked.
To apply Coccinelle to a specific directory, ``M=`` can be used.
For example, to check drivers/net/wireless/ one may write::
make coccicheck M=drivers/net/wireless/
To apply Coccinelle on a file basis, instead of a directory basis, the
following command may be used::
make C=1 CHECK="scripts/coccicheck"
To check only newly edited code, use the value 2 for the C flag, i.e.::
make C=2 CHECK="scripts/coccicheck"
In these modes, which works on a file basis, there is no information
about semantic patches displayed, and no commit message proposed.
This runs every semantic patch in scripts/coccinelle by default. The
COCCI variable may additionally be used to only apply a single
semantic patch as shown in the previous section.
The "report" mode is the default. You can select another one with the
MODE variable explained above.
Debugging Coccinelle SmPL patches
---------------------------------
Using coccicheck is best as it provides in the spatch command line
include options matching the options used when we compile the kernel.
You can learn what these options are by using V=1, you could then
manually run Coccinelle with debug options added.
Alternatively you can debug running Coccinelle against SmPL patches
by asking for stderr to be redirected to stderr, by default stderr
is redirected to /dev/null, if you'd like to capture stderr you
can specify the ``DEBUG_FILE="file.txt"`` option to coccicheck. For
instance::
rm -f cocci.err
make coccicheck COCCI=scripts/coccinelle/free/kfree.cocci MODE=report DEBUG_FILE=cocci.err
cat cocci.err
You can use SPFLAGS to add debugging flags, for instance you may want to
add both --profile --show-trying to SPFLAGS when debugging. For instance
you may want to use::
rm -f err.log
export COCCI=scripts/coccinelle/misc/irqf_oneshot.cocci
make coccicheck DEBUG_FILE="err.log" MODE=report SPFLAGS="--profile --show-trying" M=./drivers/mfd/arizona-irq.c
err.log will now have the profiling information, while stdout will
provide some progress information as Coccinelle moves forward with
work.
DEBUG_FILE support is only supported when using coccinelle >= 1.0.2.
.cocciconfig support
--------------------
Coccinelle supports reading .cocciconfig for default Coccinelle options that
should be used every time spatch is spawned, the order of precedence for
variables for .cocciconfig is as follows:
- Your current user's home directory is processed first
- Your directory from which spatch is called is processed next
- The directory provided with the --dir option is processed last, if used
Since coccicheck runs through make, it naturally runs from the kernel
proper dir, as such the second rule above would be implied for picking up a
.cocciconfig when using ``make coccicheck``.
``make coccicheck`` also supports using M= targets.If you do not supply
any M= target, it is assumed you want to target the entire kernel.
The kernel coccicheck script has::
if [ "$KBUILD_EXTMOD" = "" ] ; then
OPTIONS="--dir $srctree $COCCIINCLUDE"
else
OPTIONS="--dir $KBUILD_EXTMOD $COCCIINCLUDE"
fi
KBUILD_EXTMOD is set when an explicit target with M= is used. For both cases
the spatch --dir argument is used, as such third rule applies when whether M=
is used or not, and when M= is used the target directory can have its own
.cocciconfig file. When M= is not passed as an argument to coccicheck the
target directory is the same as the directory from where spatch was called.
If not using the kernel's coccicheck target, keep the above precedence
order logic of .cocciconfig reading. If using the kernel's coccicheck target,
override any of the kernel's .coccicheck's settings using SPFLAGS.
We help Coccinelle when used against Linux with a set of sensible defaults
options for Linux with our own Linux .cocciconfig. This hints to coccinelle
git can be used for ``git grep`` queries over coccigrep. A timeout of 200
seconds should suffice for now.
The options picked up by coccinelle when reading a .cocciconfig do not appear
as arguments to spatch processes running on your system, to confirm what
options will be used by Coccinelle run::
spatch --print-options-only
You can override with your own preferred index option by using SPFLAGS. Take
note that when there are conflicting options Coccinelle takes precedence for
the last options passed. Using .cocciconfig is possible to use idutils, however
given the order of precedence followed by Coccinelle, since the kernel now
carries its own .cocciconfig, you will need to use SPFLAGS to use idutils if
desired. See below section "Additional flags" for more details on how to use
idutils.
Additional flags
----------------
Additional flags can be passed to spatch through the SPFLAGS
variable. This works as Coccinelle respects the last flags
given to it when options are in conflict. ::
make SPFLAGS=--use-glimpse coccicheck
Coccinelle supports idutils as well but requires coccinelle >= 1.0.6.
When no ID file is specified coccinelle assumes your ID database file
is in the file .id-utils.index on the top level of the kernel, coccinelle
carries a script scripts/idutils_index.sh which creates the database with::
mkid -i C --output .id-utils.index
If you have another database filename you can also just symlink with this
name. ::
make SPFLAGS=--use-idutils coccicheck
Alternatively you can specify the database filename explicitly, for
instance::
make SPFLAGS="--use-idutils /full-path/to/ID" coccicheck
See ``spatch --help`` to learn more about spatch options.
Note that the ``--use-glimpse`` and ``--use-idutils`` options
require external tools for indexing the code. None of them is
thus active by default. However, by indexing the code with
one of these tools, and according to the cocci file used,
spatch could proceed the entire code base more quickly.
SmPL patch specific options
---------------------------
SmPL patches can have their own requirements for options passed
to Coccinelle. SmPL patch specific options can be provided by
providing them at the top of the SmPL patch, for instance::
// Options: --no-includes --include-headers
SmPL patch Coccinelle requirements
----------------------------------
As Coccinelle features get added some more advanced SmPL patches
may require newer versions of Coccinelle. If an SmPL patch requires
at least a version of Coccinelle, this can be specified as follows,
as an example if requiring at least Coccinelle >= 1.0.5::
// Requires: 1.0.5
Proposing new semantic patches
-------------------------------
New semantic patches can be proposed and submitted by kernel
developers. For sake of clarity, they should be organized in the
sub-directories of ``scripts/coccinelle/``.
Detailed description of the ``report`` mode
-------------------------------------------
``report`` generates a list in the following format::
file:line:column-column: message
Example
~~~~~~~
Running::
make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci
will execute the following part of the SmPL script::
<smpl>
@r depends on !context && !patch && (org || report)@
expression x;
position p;
@@
ERR_PTR@p(PTR_ERR(x))
@script:python depends on report@
p << r.p;
x << r.x;
@@
msg="ERR_CAST can be used with %s" % (x)
coccilib.report.print_report(p[0], msg)
</smpl>
This SmPL excerpt generates entries on the standard output, as
illustrated below::
/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
Detailed description of the ``patch`` mode
------------------------------------------
When the ``patch`` mode is available, it proposes a fix for each problem
identified.
Example
~~~~~~~
Running::
make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci
will execute the following part of the SmPL script::
<smpl>
@ depends on !context && patch && !org && !report @
expression x;
@@
- ERR_PTR(PTR_ERR(x))
+ ERR_CAST(x)
</smpl>
This SmPL excerpt generates patch hunks on the standard output, as
illustrated below::
diff -u -p a/crypto/ctr.c b/crypto/ctr.c
--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
+++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
- return ERR_PTR(PTR_ERR(alg));
+ return ERR_CAST(alg);
/* Block size must be >= 4 bytes. */
err = -EINVAL;
Detailed description of the ``context`` mode
--------------------------------------------
``context`` highlights lines of interest and their context
in a diff-like style.
**NOTE**: The diff-like output generated is NOT an applicable patch. The
intent of the ``context`` mode is to highlight the important lines
(annotated with minus, ``-``) and gives some surrounding context
lines around. This output can be used with the diff mode of
Emacs to review the code.
Example
~~~~~~~
Running::
make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci
will execute the following part of the SmPL script::
<smpl>
@ depends on context && !patch && !org && !report@
expression x;
@@
* ERR_PTR(PTR_ERR(x))
</smpl>
This SmPL excerpt generates diff hunks on the standard output, as
illustrated below::
diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
--- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
+++ /tmp/nothing
@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
CRYPTO_ALG_TYPE_MASK);
if (IS_ERR(alg))
- return ERR_PTR(PTR_ERR(alg));
/* Block size must be >= 4 bytes. */
err = -EINVAL;
Detailed description of the ``org`` mode
----------------------------------------
``org`` generates a report in the Org mode format of Emacs.
Example
~~~~~~~
Running::
make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci
will execute the following part of the SmPL script::
<smpl>
@r depends on !context && !patch && (org || report)@
expression x;
position p;
@@
ERR_PTR@p(PTR_ERR(x))
@script:python depends on org@
p << r.p;
x << r.x;
@@
msg="ERR_CAST can be used with %s" % (x)
msg_safe=msg.replace("[","@(").replace("]",")")
coccilib.org.print_todo(p[0], msg_safe)
</smpl>
This SmPL excerpt generates Org entries on the standard output, as
illustrated below::
* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
+10
View File
@@ -0,0 +1,10 @@
# -*- coding: utf-8; mode: python -*-
project = "Development tools for the kernel"
tags.add("subproject")
latex_documents = [
('index', 'dev-tools.tex', project,
'The kernel development community', 'manual'),
]
+270
View File
@@ -0,0 +1,270 @@
Using gcov with the Linux kernel
================================
gcov profiling kernel support enables the use of GCC's coverage testing
tool gcov_ with the Linux kernel. Coverage data of a running kernel
is exported in gcov-compatible format via the "gcov" debugfs directory.
To get coverage data for a specific file, change to the kernel build
directory and use gcov with the ``-o`` option as follows (requires root)::
# cd /tmp/linux-out
# gcov -o /sys/kernel/debug/gcov/tmp/linux-out/kernel spinlock.c
This will create source code files annotated with execution counts
in the current directory. In addition, graphical gcov front-ends such
as lcov_ can be used to automate the process of collecting data
for the entire kernel and provide coverage overviews in HTML format.
Possible uses:
* debugging (has this line been reached at all?)
* test improvement (how do I change my test to cover these lines?)
* minimizing kernel configurations (do I need this option if the
associated code is never run?)
.. _gcov: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
.. _lcov: http://ltp.sourceforge.net/coverage/lcov.php
Preparation
-----------
Configure the kernel with::
CONFIG_DEBUG_FS=y
CONFIG_GCOV_KERNEL=y
and to get coverage data for the entire kernel::
CONFIG_GCOV_PROFILE_ALL=y
Note that kernels compiled with profiling flags will be significantly
larger and run slower. Also CONFIG_GCOV_PROFILE_ALL may not be supported
on all architectures.
Profiling data will only become accessible once debugfs has been
mounted::
mount -t debugfs none /sys/kernel/debug
Customization
-------------
To enable profiling for specific files or directories, add a line
similar to the following to the respective kernel Makefile:
- For a single file (e.g. main.o)::
GCOV_PROFILE_main.o := y
- For all files in one directory::
GCOV_PROFILE := y
To exclude files from being profiled even when CONFIG_GCOV_PROFILE_ALL
is specified, use::
GCOV_PROFILE_main.o := n
and::
GCOV_PROFILE := n
Only files which are linked to the main kernel image or are compiled as
kernel modules are supported by this mechanism.
Files
-----
The gcov kernel support creates the following files in debugfs:
``/sys/kernel/debug/gcov``
Parent directory for all gcov-related files.
``/sys/kernel/debug/gcov/reset``
Global reset file: resets all coverage data to zero when
written to.
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcda``
The actual gcov data file as understood by the gcov
tool. Resets file coverage data to zero when written to.
``/sys/kernel/debug/gcov/path/to/compile/dir/file.gcno``
Symbolic link to a static data file required by the gcov
tool. This file is generated by gcc when compiling with
option ``-ftest-coverage``.
Modules
-------
Kernel modules may contain cleanup code which is only run during
module unload time. The gcov mechanism provides a means to collect
coverage data for such code by keeping a copy of the data associated
with the unloaded module. This data remains available through debugfs.
Once the module is loaded again, the associated coverage counters are
initialized with the data from its previous instantiation.
This behavior can be deactivated by specifying the gcov_persist kernel
parameter::
gcov_persist=0
At run-time, a user can also choose to discard data for an unloaded
module by writing to its data file or the global reset file.
Separated build and test machines
---------------------------------
The gcov kernel profiling infrastructure is designed to work out-of-the
box for setups where kernels are built and run on the same machine. In
cases where the kernel runs on a separate machine, special preparations
must be made, depending on where the gcov tool is used:
a) gcov is run on the TEST machine
The gcov tool version on the test machine must be compatible with the
gcc version used for kernel build. Also the following files need to be
copied from build to test machine:
from the source tree:
- all C source files + headers
from the build tree:
- all C source files + headers
- all .gcda and .gcno files
- all links to directories
It is important to note that these files need to be placed into the
exact same file system location on the test machine as on the build
machine. If any of the path components is symbolic link, the actual
directory needs to be used instead (due to make's CURDIR handling).
b) gcov is run on the BUILD machine
The following files need to be copied after each test case from test
to build machine:
from the gcov directory in sysfs:
- all .gcda files
- all links to .gcno files
These files can be copied to any location on the build machine. gcov
must then be called with the -o option pointing to that directory.
Example directory setup on the build machine::
/tmp/linux: kernel source tree
/tmp/out: kernel build directory as specified by make O=
/tmp/coverage: location of the files copied from the test machine
[user@build] cd /tmp/out
[user@build] gcov -o /tmp/coverage/tmp/out/init main.c
Note on compilers
-----------------
GCC and LLVM gcov tools are not necessarily compatible. Use gcov_ to work with
GCC-generated .gcno and .gcda files, and use llvm-cov_ for Clang.
.. _gcov: http://gcc.gnu.org/onlinedocs/gcc/Gcov.html
.. _llvm-cov: https://llvm.org/docs/CommandGuide/llvm-cov.html
Build differences between GCC and Clang gcov are handled by Kconfig. It
automatically selects the appropriate gcov format depending on the detected
toolchain.
Troubleshooting
---------------
Problem
Compilation aborts during linker step.
Cause
Profiling flags are specified for source files which are not
linked to the main kernel or which are linked by a custom
linker procedure.
Solution
Exclude affected source files from profiling by specifying
``GCOV_PROFILE := n`` or ``GCOV_PROFILE_basename.o := n`` in the
corresponding Makefile.
Problem
Files copied from sysfs appear empty or incomplete.
Cause
Due to the way seq_file works, some tools such as cp or tar
may not correctly copy files from sysfs.
Solution
Use ``cat``' to read ``.gcda`` files and ``cp -d`` to copy links.
Alternatively use the mechanism shown in Appendix B.
Appendix A: gather_on_build.sh
------------------------------
Sample script to gather coverage meta files on the build machine
(see 6a):
.. code-block:: sh
#!/bin/bash
KSRC=$1
KOBJ=$2
DEST=$3
if [ -z "$KSRC" ] || [ -z "$KOBJ" ] || [ -z "$DEST" ]; then
echo "Usage: $0 <ksrc directory> <kobj directory> <output.tar.gz>" >&2
exit 1
fi
KSRC=$(cd $KSRC; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
KOBJ=$(cd $KOBJ; printf "all:\n\t@echo \${CURDIR}\n" | make -f -)
find $KSRC $KOBJ \( -name '*.gcno' -o -name '*.[ch]' -o -type l \) -a \
-perm /u+r,g+r | tar cfz $DEST -P -T -
if [ $? -eq 0 ] ; then
echo "$DEST successfully created, copy to test system and unpack with:"
echo " tar xfz $DEST -P"
else
echo "Could not create file $DEST"
fi
Appendix B: gather_on_test.sh
-----------------------------
Sample script to gather coverage data files on the test machine
(see 6b):
.. code-block:: sh
#!/bin/bash -e
DEST=$1
GCDA=/sys/kernel/debug/gcov
if [ -z "$DEST" ] ; then
echo "Usage: $0 <output.tar.gz>" >&2
exit 1
fi
TEMPDIR=$(mktemp -d)
echo Collecting data..
find $GCDA -type d -exec mkdir -p $TEMPDIR/\{\} \;
find $GCDA -name '*.gcda' -exec sh -c 'cat < $0 > '$TEMPDIR'/$0' {} \;
find $GCDA -name '*.gcno' -exec sh -c 'cp -d $0 '$TEMPDIR'/$0' {} \;
tar czf $DEST -C $TEMPDIR sys
rm -rf $TEMPDIR
echo "$DEST successfully created, copy to build system and unpack with:"
echo " tar xfz $DEST"
@@ -0,0 +1,175 @@
.. highlight:: none
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, 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
or
- during runtime by issuing "gdbserver" from the QEMU monitor
console
- cd /path/to/linux-build
- 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::
add-auto-load-safe-path /path/to/linux-build
to ~/.gdbinit. See gdb help for more details.
- Attach to the booted guest::
(gdb) target remote :1234
Examples of using the Linux-provided gdb helpers
------------------------------------------------
- Load module (and main kernel) symbols::
(gdb) lx-symbols
loading vmlinux
scanning for modules in /home/user/linux/build
loading @0xffffffffa0020000: /home/user/linux/build/net/netfilter/xt_tcpudp.ko
loading @0xffffffffa0016000: /home/user/linux/build/net/netfilter/xt_pkttype.ko
loading @0xffffffffa0002000: /home/user/linux/build/net/netfilter/xt_limit.ko
loading @0xffffffffa00ca000: /home/user/linux/build/net/packet/af_packet.ko
loading @0xffffffffa003c000: /home/user/linux/build/fs/fuse/fuse.ko
...
loading @0xffffffffa0000000: /home/user/linux/build/drivers/ata/ata_generic.ko
- Set a breakpoint on some not yet loaded module function, e.g.::
(gdb) b btrfs_init_sysfs
Function "btrfs_init_sysfs" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (btrfs_init_sysfs) pending.
- Continue the target::
(gdb) c
- Load the module on the target and watch the symbols being loaded as well as
the breakpoint hit::
loading @0xffffffffa0034000: /home/user/linux/build/lib/libcrc32c.ko
loading @0xffffffffa0050000: /home/user/linux/build/lib/lzo/lzo_compress.ko
loading @0xffffffffa006e000: /home/user/linux/build/lib/zlib_deflate/zlib_deflate.ko
loading @0xffffffffa01b1000: /home/user/linux/build/fs/btrfs/btrfs.ko
Breakpoint 1, btrfs_init_sysfs () at /home/user/linux/fs/btrfs/sysfs.c:36
36 btrfs_kset = kset_create_and_add("btrfs", NULL, fs_kobj);
- Dump the log buffer of the target kernel::
(gdb) lx-dmesg
[ 0.000000] Initializing cgroup subsys cpuset
[ 0.000000] Initializing cgroup subsys cpu
[ 0.000000] Linux version 3.8.0-rc4-dbg+ (...
[ 0.000000] Command line: root=/dev/sda2 resume=/dev/sda1 vga=0x314
[ 0.000000] e820: BIOS-provided physical RAM map:
[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[ 0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
....
- Examine fields of the current task struct::
(gdb) p $lx_current().pid
$1 = 4998
(gdb) p $lx_current().comm
$2 = "modprobe\000\000\000\000\000\000\000"
- Make use of the per-cpu function for the current or a specified CPU::
(gdb) p $lx_per_cpu("runqueues").nr_running
$3 = 1
(gdb) p $lx_per_cpu("runqueues", 2).nr_running
$4 = 0
- Dig into hrtimers using the container_of helper::
(gdb) set $next = $lx_per_cpu("hrtimer_bases").clock_base[0].active.next
(gdb) p *$container_of($next, "struct hrtimer", "node")
$5 = {
node = {
node = {
__rb_parent_color = 18446612133355256072,
rb_right = 0x0 <irq_stack_union>,
rb_left = 0x0 <irq_stack_union>
},
expires = {
tv64 = 1835268000000
}
},
_softexpires = {
tv64 = 1835268000000
},
function = 0xffffffff81078232 <tick_sched_timer>,
base = 0xffff88003fd0d6f0,
state = 1,
start_pid = 0,
start_site = 0xffffffff81055c1f <hrtimer_start_range_ns+20>,
start_comm = "swapper/2\000\000\000\000\000\000"
}
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::
(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-dmesg -- Print Linux kernel log buffer
lx-lsmod -- List currently loaded modules
lx-symbols -- (Re-)load symbols of Linux kernel and currently loaded modules
Detailed help can be obtained via "help <command-name>" for commands and "help
function <function-name>" for convenience functions.
+34
View File
@@ -0,0 +1,34 @@
================================
Development tools for the kernel
================================
This document is a collection of documents about development tools that can
be used to work on the kernel. For now, the documents have been pulled
together without any significant effot to integrate them into a coherent
whole; patches welcome!
.. class:: toc-title
Table of contents
.. toctree::
:maxdepth: 2
coccinelle
sparse
kcov
gcov
kasan
ubsan
kmemleak
gdb-kernel-debugging
kgdb
kselftest
.. only:: subproject and html
Indices
=======
* :ref:`genindex`
+217
View File
@@ -0,0 +1,217 @@
The Kernel Address Sanitizer (KASAN)
====================================
Overview
--------
KernelAddressSANitizer (KASAN) is a dynamic memory error detector designed to
find out-of-bound and use-after-free bugs. KASAN has two modes: generic KASAN
(similar to userspace ASan) and software tag-based KASAN (similar to userspace
HWASan).
KASAN uses compile-time instrumentation to insert validity checks before every
memory access, and therefore requires a compiler version that supports that.
Generic KASAN is supported in both GCC and Clang. With GCC it requires version
4.9.2 or later for basic support and version 5.0 or later for detection of
out-of-bounds accesses for stack and global variables and for inline
instrumentation mode (see the Usage section). With Clang it requires version
7.0.0 or later and it doesn't support detection of out-of-bounds accesses for
global variables yet.
Tag-based KASAN is only supported in Clang and requires version 7.0.0 or later.
Currently generic KASAN is supported for the x86_64, arm64, xtensa and s390
architectures, and tag-based KASAN is supported only for arm64.
Usage
-----
To enable KASAN configure kernel with::
CONFIG_KASAN = y
and choose between CONFIG_KASAN_GENERIC (to enable generic KASAN) and
CONFIG_KASAN_SW_TAGS (to enable software tag-based KASAN).
You also need to choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE.
Outline and inline are compiler instrumentation types. The former produces
smaller binary while the latter is 1.1 - 2 times faster.
Both KASAN modes work with both SLUB and SLAB memory allocators.
For better bug detection and nicer reporting, enable CONFIG_STACKTRACE.
To disable instrumentation for specific files or directories, add a line
similar to the following to the respective kernel Makefile:
- For a single file (e.g. main.o)::
KASAN_SANITIZE_main.o := n
- For all files in one directory::
KASAN_SANITIZE := n
Error reports
~~~~~~~~~~~~~
A typical out-of-bounds access generic KASAN report looks like this::
==================================================================
BUG: KASAN: slab-out-of-bounds in kmalloc_oob_right+0xa8/0xbc [test_kasan]
Write of size 1 at addr ffff8801f44ec37b by task insmod/2760
CPU: 1 PID: 2760 Comm: insmod Not tainted 4.19.0-rc3+ #698
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
Call Trace:
dump_stack+0x94/0xd8
print_address_description+0x73/0x280
kasan_report+0x144/0x187
__asan_report_store1_noabort+0x17/0x20
kmalloc_oob_right+0xa8/0xbc [test_kasan]
kmalloc_tests_init+0x16/0x700 [test_kasan]
do_one_initcall+0xa5/0x3ae
do_init_module+0x1b6/0x547
load_module+0x75df/0x8070
__do_sys_init_module+0x1c6/0x200
__x64_sys_init_module+0x6e/0xb0
do_syscall_64+0x9f/0x2c0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f96443109da
RSP: 002b:00007ffcf0b51b08 EFLAGS: 00000202 ORIG_RAX: 00000000000000af
RAX: ffffffffffffffda RBX: 000055dc3ee521a0 RCX: 00007f96443109da
RDX: 00007f96445cff88 RSI: 0000000000057a50 RDI: 00007f9644992000
RBP: 000055dc3ee510b0 R08: 0000000000000003 R09: 0000000000000000
R10: 00007f964430cd0a R11: 0000000000000202 R12: 00007f96445cff88
R13: 000055dc3ee51090 R14: 0000000000000000 R15: 0000000000000000
Allocated by task 2760:
save_stack+0x43/0xd0
kasan_kmalloc+0xa7/0xd0
kmem_cache_alloc_trace+0xe1/0x1b0
kmalloc_oob_right+0x56/0xbc [test_kasan]
kmalloc_tests_init+0x16/0x700 [test_kasan]
do_one_initcall+0xa5/0x3ae
do_init_module+0x1b6/0x547
load_module+0x75df/0x8070
__do_sys_init_module+0x1c6/0x200
__x64_sys_init_module+0x6e/0xb0
do_syscall_64+0x9f/0x2c0
entry_SYSCALL_64_after_hwframe+0x44/0xa9
Freed by task 815:
save_stack+0x43/0xd0
__kasan_slab_free+0x135/0x190
kasan_slab_free+0xe/0x10
kfree+0x93/0x1a0
umh_complete+0x6a/0xa0
call_usermodehelper_exec_async+0x4c3/0x640
ret_from_fork+0x35/0x40
The buggy address belongs to the object at ffff8801f44ec300
which belongs to the cache kmalloc-128 of size 128
The buggy address is located 123 bytes inside of
128-byte region [ffff8801f44ec300, ffff8801f44ec380)
The buggy address belongs to the page:
page:ffffea0007d13b00 count:1 mapcount:0 mapping:ffff8801f7001640 index:0x0
flags: 0x200000000000100(slab)
raw: 0200000000000100 ffffea0007d11dc0 0000001a0000001a ffff8801f7001640
raw: 0000000000000000 0000000080150015 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8801f44ec200: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
ffff8801f44ec280: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff8801f44ec300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03
^
ffff8801f44ec380: fc fc fc fc fc fc fc fc fb fb fb fb fb fb fb fb
ffff8801f44ec400: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
==================================================================
The header of the report provides a short summary of what kind of bug happened
and what kind of access caused it. It's followed by a stack trace of the bad
access, a stack trace of where the accessed memory was allocated (in case bad
access happens on a slab object), and a stack trace of where the object was
freed (in case of a use-after-free bug report). Next comes a description of
the accessed slab object and information about the accessed memory page.
In the last section the report shows memory state around the accessed address.
Reading this part requires some understanding of how KASAN works.
The state of each 8 aligned bytes of memory is encoded in one shadow byte.
Those 8 bytes can be accessible, partially accessible, freed or be a redzone.
We use the following encoding for each shadow byte: 0 means that all 8 bytes
of the corresponding memory region are accessible; number N (1 <= N <= 7) means
that the first N bytes are accessible, and other (8 - N) bytes are not;
any negative value indicates that the entire 8-byte word is inaccessible.
We use different negative values to distinguish between different kinds of
inaccessible memory like redzones or freed memory (see mm/kasan/kasan.h).
In the report above the arrows point to the shadow byte 03, which means that
the accessed address is partially accessible.
For tag-based KASAN this last report section shows the memory tags around the
accessed address (see Implementation details section).
Implementation details
----------------------
Generic KASAN
~~~~~~~~~~~~~
From a high level, our approach to memory error detection is similar to that
of kmemcheck: use shadow memory to record whether each byte of memory is safe
to access, and use compile-time instrumentation to insert checks of shadow
memory on each memory access.
Generic KASAN dedicates 1/8th of kernel memory to its shadow memory (e.g. 16TB
to cover 128TB on x86_64) and uses direct mapping with a scale and offset to
translate a memory address to its corresponding shadow address.
Here is the function which translates an address to its corresponding shadow
address::
static inline void *kasan_mem_to_shadow(const void *addr)
{
return ((unsigned long)addr >> KASAN_SHADOW_SCALE_SHIFT)
+ KASAN_SHADOW_OFFSET;
}
where ``KASAN_SHADOW_SCALE_SHIFT = 3``.
Compile-time instrumentation is used to insert memory access checks. Compiler
inserts function calls (__asan_load*(addr), __asan_store*(addr)) before each
memory access of size 1, 2, 4, 8 or 16. These functions check whether memory
access is valid or not by checking corresponding shadow memory.
GCC 5.0 has possibility to perform inline instrumentation. Instead of making
function calls GCC directly inserts the code to check the shadow memory.
This option significantly enlarges kernel but it gives x1.1-x2 performance
boost over outline instrumented kernel.
Software tag-based KASAN
~~~~~~~~~~~~~~~~~~~~~~~~
Tag-based KASAN uses the Top Byte Ignore (TBI) feature of modern arm64 CPUs to
store a pointer tag in the top byte of kernel pointers. Like generic KASAN it
uses shadow memory to store memory tags associated with each 16-byte memory
cell (therefore it dedicates 1/16th of the kernel memory for shadow memory).
On each memory allocation tag-based KASAN generates a random tag, tags the
allocated memory with this tag, and embeds this tag into the returned pointer.
Software tag-based KASAN uses compile-time instrumentation to insert checks
before each memory access. These checks make sure that tag of the memory that
is being accessed is equal to tag of the pointer that is used to access this
memory. In case of a tag mismatch tag-based KASAN prints a bug report.
Software tag-based KASAN also has two instrumentation modes (outline, that
emits callbacks to check memory accesses; and inline, that performs the shadow
memory checks inline). With outline instrumentation mode, a bug report is
simply printed from the function that performs the access check. With inline
instrumentation a brk instruction is emitted by the compiler, and a dedicated
brk handler is used to print bug reports.
A potential expansion of this mode is a hardware tag-based mode, which would
use hardware memory tagging support instead of compiler instrumentation and
manual shadow memory manipulation.
+333
View File
@@ -0,0 +1,333 @@
kcov: code coverage for fuzzing
===============================
kcov exposes kernel code coverage information in a form suitable for coverage-
guided fuzzing (randomized testing). Coverage data of a running kernel is
exported via the "kcov" debugfs file. Coverage collection is enabled on a task
basis, and thus it can capture precise coverage of a single system call.
Note that kcov does not aim to collect as much coverage as possible. It aims
to collect more or less stable coverage that is function of syscall inputs.
To achieve this goal it does not collect coverage in soft/hard interrupts
and instrumentation of some inherently non-deterministic parts of kernel is
disabled (e.g. scheduler, locking).
kcov is also able to collect comparison operands from the instrumented code
(this feature currently requires that the kernel is compiled with clang).
Prerequisites
-------------
Configure the kernel with::
CONFIG_KCOV=y
CONFIG_KCOV requires gcc built on revision 231296 or later.
If the comparison operands need to be collected, set::
CONFIG_KCOV_ENABLE_COMPARISONS=y
Profiling data will only become accessible once debugfs has been mounted::
mount -t debugfs none /sys/kernel/debug
Coverage collection
-------------------
The following program demonstrates coverage collection from within a test
program using kcov:
.. code-block:: c
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
#define KCOV_ENABLE _IO('c', 100)
#define KCOV_DISABLE _IO('c', 101)
#define COVER_SIZE (64<<10)
#define KCOV_TRACE_PC 0
#define KCOV_TRACE_CMP 1
int main(int argc, char **argv)
{
int fd;
unsigned long *cover, n, i;
/* A single fd descriptor allows coverage collection on a single
* thread.
*/
fd = open("/sys/kernel/debug/kcov", O_RDWR);
if (fd == -1)
perror("open"), exit(1);
/* Setup trace mode and trace size. */
if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
perror("ioctl"), exit(1);
/* Mmap buffer shared between kernel- and user-space. */
cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if ((void*)cover == MAP_FAILED)
perror("mmap"), exit(1);
/* Enable coverage collection on the current thread. */
if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_PC))
perror("ioctl"), exit(1);
/* Reset coverage from the tail of the ioctl() call. */
__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
/* That's the target syscal call. */
read(-1, NULL, 0);
/* Read number of PCs collected. */
n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
for (i = 0; i < n; i++)
printf("0x%lx\n", cover[i + 1]);
/* Disable coverage collection for the current thread. After this call
* coverage can be enabled for a different thread.
*/
if (ioctl(fd, KCOV_DISABLE, 0))
perror("ioctl"), exit(1);
/* Free resources. */
if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
perror("munmap"), exit(1);
if (close(fd))
perror("close"), exit(1);
return 0;
}
After piping through addr2line output of the program looks as follows::
SyS_read
fs/read_write.c:562
__fdget_pos
fs/file.c:774
__fget_light
fs/file.c:746
__fget_light
fs/file.c:750
__fget_light
fs/file.c:760
__fdget_pos
fs/file.c:784
SyS_read
fs/read_write.c:562
If a program needs to collect coverage from several threads (independently),
it needs to open /sys/kernel/debug/kcov in each thread separately.
The interface is fine-grained to allow efficient forking of test processes.
That is, a parent process opens /sys/kernel/debug/kcov, enables trace mode,
mmaps coverage buffer and then forks child processes in a loop. Child processes
only need to enable coverage (disable happens automatically on thread end).
Comparison operands collection
------------------------------
Comparison operands collection is similar to coverage collection:
.. code-block:: c
/* Same includes and defines as above. */
/* Number of 64-bit words per record. */
#define KCOV_WORDS_PER_CMP 4
/*
* The format for the types of collected comparisons.
*
* Bit 0 shows whether one of the arguments is a compile-time constant.
* Bits 1 & 2 contain log2 of the argument size, up to 8 bytes.
*/
#define KCOV_CMP_CONST (1 << 0)
#define KCOV_CMP_SIZE(n) ((n) << 1)
#define KCOV_CMP_MASK KCOV_CMP_SIZE(3)
int main(int argc, char **argv)
{
int fd;
uint64_t *cover, type, arg1, arg2, is_const, size;
unsigned long n, i;
fd = open("/sys/kernel/debug/kcov", O_RDWR);
if (fd == -1)
perror("open"), exit(1);
if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
perror("ioctl"), exit(1);
/*
* Note that the buffer pointer is of type uint64_t*, because all
* the comparison operands are promoted to uint64_t.
*/
cover = (uint64_t *)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if ((void*)cover == MAP_FAILED)
perror("mmap"), exit(1);
/* Note KCOV_TRACE_CMP instead of KCOV_TRACE_PC. */
if (ioctl(fd, KCOV_ENABLE, KCOV_TRACE_CMP))
perror("ioctl"), exit(1);
__atomic_store_n(&cover[0], 0, __ATOMIC_RELAXED);
read(-1, NULL, 0);
/* Read number of comparisons collected. */
n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
for (i = 0; i < n; i++) {
type = cover[i * KCOV_WORDS_PER_CMP + 1];
/* arg1 and arg2 - operands of the comparison. */
arg1 = cover[i * KCOV_WORDS_PER_CMP + 2];
arg2 = cover[i * KCOV_WORDS_PER_CMP + 3];
/* ip - caller address. */
ip = cover[i * KCOV_WORDS_PER_CMP + 4];
/* size of the operands. */
size = 1 << ((type & KCOV_CMP_MASK) >> 1);
/* is_const - true if either operand is a compile-time constant.*/
is_const = type & KCOV_CMP_CONST;
printf("ip: 0x%lx type: 0x%lx, arg1: 0x%lx, arg2: 0x%lx, "
"size: %lu, %s\n",
ip, type, arg1, arg2, size,
is_const ? "const" : "non-const");
}
if (ioctl(fd, KCOV_DISABLE, 0))
perror("ioctl"), exit(1);
/* Free resources. */
if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
perror("munmap"), exit(1);
if (close(fd))
perror("close"), exit(1);
return 0;
}
Note that the kcov modes (coverage collection or comparison operands) are
mutually exclusive.
Remote coverage collection
--------------------------
With KCOV_ENABLE coverage is collected only for syscalls that are issued
from the current process. With KCOV_REMOTE_ENABLE it's possible to collect
coverage for arbitrary parts of the kernel code, provided that those parts
are annotated with kcov_remote_start()/kcov_remote_stop().
This allows to collect coverage from two types of kernel background
threads: the global ones, that are spawned during kernel boot in a limited
number of instances (e.g. one USB hub_event() worker thread is spawned per
USB HCD); and the local ones, that are spawned when a user interacts with
some kernel interface (e.g. vhost workers).
To enable collecting coverage from a global background thread, a unique
global handle must be assigned and passed to the corresponding
kcov_remote_start() call. Then a userspace process can pass a list of such
handles to the KCOV_REMOTE_ENABLE ioctl in the handles array field of the
kcov_remote_arg struct. This will attach the used kcov device to the code
sections, that are referenced by those handles.
Since there might be many local background threads spawned from different
userspace processes, we can't use a single global handle per annotation.
Instead, the userspace process passes a non-zero handle through the
common_handle field of the kcov_remote_arg struct. This common handle gets
saved to the kcov_handle field in the current task_struct and needs to be
passed to the newly spawned threads via custom annotations. Those threads
should in turn be annotated with kcov_remote_start()/kcov_remote_stop().
Internally kcov stores handles as u64 integers. The top byte of a handle
is used to denote the id of a subsystem that this handle belongs to, and
the lower 4 bytes are used to denote the id of a thread instance within
that subsystem. A reserved value 0 is used as a subsystem id for common
handles as they don't belong to a particular subsystem. The bytes 4-7 are
currently reserved and must be zero. In the future the number of bytes
used for the subsystem or handle ids might be increased.
When a particular userspace proccess collects coverage by via a common
handle, kcov will collect coverage for each code section that is annotated
to use the common handle obtained as kcov_handle from the current
task_struct. However non common handles allow to collect coverage
selectively from different subsystems.
.. code-block:: c
struct kcov_remote_arg {
__u32 trace_mode;
__u32 area_size;
__u32 num_handles;
__aligned_u64 common_handle;
__aligned_u64 handles[0];
};
#define KCOV_INIT_TRACE _IOR('c', 1, unsigned long)
#define KCOV_DISABLE _IO('c', 101)
#define KCOV_REMOTE_ENABLE _IOW('c', 102, struct kcov_remote_arg)
#define COVER_SIZE (64 << 10)
#define KCOV_TRACE_PC 0
#define KCOV_SUBSYSTEM_COMMON (0x00ull << 56)
#define KCOV_SUBSYSTEM_USB (0x01ull << 56)
#define KCOV_SUBSYSTEM_MASK (0xffull << 56)
#define KCOV_INSTANCE_MASK (0xffffffffull)
static inline __u64 kcov_remote_handle(__u64 subsys, __u64 inst)
{
if (subsys & ~KCOV_SUBSYSTEM_MASK || inst & ~KCOV_INSTANCE_MASK)
return 0;
return subsys | inst;
}
#define KCOV_COMMON_ID 0x42
#define KCOV_USB_BUS_NUM 1
int main(int argc, char **argv)
{
int fd;
unsigned long *cover, n, i;
struct kcov_remote_arg *arg;
fd = open("/sys/kernel/debug/kcov", O_RDWR);
if (fd == -1)
perror("open"), exit(1);
if (ioctl(fd, KCOV_INIT_TRACE, COVER_SIZE))
perror("ioctl"), exit(1);
cover = (unsigned long*)mmap(NULL, COVER_SIZE * sizeof(unsigned long),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if ((void*)cover == MAP_FAILED)
perror("mmap"), exit(1);
/* Enable coverage collection via common handle and from USB bus #1. */
arg = calloc(1, sizeof(*arg) + sizeof(uint64_t));
if (!arg)
perror("calloc"), exit(1);
arg->trace_mode = KCOV_TRACE_PC;
arg->area_size = COVER_SIZE;
arg->num_handles = 1;
arg->common_handle = kcov_remote_handle(KCOV_SUBSYSTEM_COMMON,
KCOV_COMMON_ID);
arg->handles[0] = kcov_remote_handle(KCOV_SUBSYSTEM_USB,
KCOV_USB_BUS_NUM);
if (ioctl(fd, KCOV_REMOTE_ENABLE, arg))
perror("ioctl"), free(arg), exit(1);
free(arg);
/*
* Here the user needs to trigger execution of a kernel code section
* that is either annotated with the common handle, or to trigger some
* activity on USB bus #1.
*/
sleep(2);
n = __atomic_load_n(&cover[0], __ATOMIC_RELAXED);
for (i = 0; i < n; i++)
printf("0x%lx\n", cover[i + 1]);
if (ioctl(fd, KCOV_DISABLE, 0))
perror("ioctl"), exit(1);
if (munmap(cover, COVER_SIZE * sizeof(unsigned long)))
perror("munmap"), exit(1);
if (close(fd))
perror("close"), exit(1);
return 0;
}
+916
View File
@@ -0,0 +1,916 @@
=================================================
Using kgdb, kdb and the kernel debugger internals
=================================================
:Author: Jason Wessel
Introduction
============
The kernel has two different debugger front ends (kdb and kgdb) which
interface to the debug core. It is possible to use either of the
debugger front ends and dynamically transition between them if you
configure the kernel properly at compile and runtime.
Kdb is simplistic shell-style interface which you can use on a system
console with a keyboard or serial console. You can use it to inspect
memory, registers, process lists, dmesg, and even set breakpoints to
stop in a certain location. Kdb is not a source level debugger, although
you can set breakpoints and execute some basic kernel run control. Kdb
is mainly aimed at doing some analysis to aid in development or
diagnosing kernel problems. You can access some symbols by name in
kernel built-ins or in kernel modules if the code was built with
``CONFIG_KALLSYMS``.
Kgdb is intended to be used as a source level debugger for the Linux
kernel. It is used along with gdb to debug a Linux kernel. The
expectation is that gdb can be used to "break in" to the kernel to
inspect memory, variables and look through call stack information
similar to the way an application developer would use gdb to debug an
application. It is possible to place breakpoints in kernel code and
perform some limited execution stepping.
Two machines are required for using kgdb. One of these machines is a
development machine and the other is the target machine. The kernel to
be debugged runs on the target machine. The development machine runs an
instance of gdb against the vmlinux file which contains the symbols (not
a boot image such as bzImage, zImage, uImage...). In gdb the developer
specifies the connection parameters and connects to kgdb. The type of
connection a developer makes with gdb depends on the availability of
kgdb I/O modules compiled as built-ins or loadable kernel modules in the
test machine's kernel.
Compiling a kernel
==================
- In order to enable compilation of kdb, you must first enable kgdb.
- The kgdb test compile options are described in the kgdb test suite
chapter.
Kernel config options for kgdb
------------------------------
To enable ``CONFIG_KGDB`` you should look under
:menuselection:`Kernel hacking --> Kernel debugging` and select
:menuselection:`KGDB: kernel debugger`.
While it is not a hard requirement that you have symbols in your vmlinux
file, gdb tends not to be very useful without the symbolic data, so you
will want to turn on ``CONFIG_DEBUG_INFO`` which is called
:menuselection:`Compile the kernel with debug info` in the config menu.
It is advised, but not required, that you turn on the
``CONFIG_FRAME_POINTER`` kernel option which is called :menuselection:`Compile
the kernel with frame pointers` in the config menu. This option inserts code
to into the compiled executable which saves the frame information in
registers or on the stack at different points which allows a debugger
such as gdb to more accurately construct stack back traces while
debugging the kernel.
If the architecture that you are using supports the kernel option
``CONFIG_STRICT_KERNEL_RWX``, you should consider turning it off. This
option will prevent the use of software breakpoints because it marks
certain regions of the kernel's memory space as read-only. If kgdb
supports it for the architecture you are using, you can use hardware
breakpoints if you desire to run with the ``CONFIG_STRICT_KERNEL_RWX``
option turned on, else you need to turn off this option.
Next you should choose one of more I/O drivers to interconnect debugging
host and debugged target. Early boot debugging requires a KGDB I/O
driver that supports early debugging and the driver must be built into
the kernel directly. Kgdb I/O driver configuration takes place via
kernel or module parameters which you can learn more about in the in the
section that describes the parameter kgdboc.
Here is an example set of ``.config`` symbols to enable or disable for kgdb::
# CONFIG_STRICT_KERNEL_RWX is not set
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
Kernel config options for kdb
-----------------------------
Kdb is quite a bit more complex than the simple gdbstub sitting on top
of the kernel's debug core. Kdb must implement a shell, and also adds
some helper functions in other parts of the kernel, responsible for
printing out interesting data such as what you would see if you ran
``lsmod``, or ``ps``. In order to build kdb into the kernel you follow the
same steps as you would for kgdb.
The main config option for kdb is ``CONFIG_KGDB_KDB`` which is called
:menuselection:`KGDB_KDB: include kdb frontend for kgdb` in the config menu.
In theory you would have already also selected an I/O driver such as the
``CONFIG_KGDB_SERIAL_CONSOLE`` interface if you plan on using kdb on a
serial port, when you were configuring kgdb.
If you want to use a PS/2-style keyboard with kdb, you would select
``CONFIG_KDB_KEYBOARD`` which is called :menuselection:`KGDB_KDB: keyboard as
input device` in the config menu. The ``CONFIG_KDB_KEYBOARD`` option is not
used for anything in the gdb interface to kgdb. The ``CONFIG_KDB_KEYBOARD``
option only works with kdb.
Here is an example set of ``.config`` symbols to enable/disable kdb::
# CONFIG_STRICT_KERNEL_RWX is not set
CONFIG_FRAME_POINTER=y
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
CONFIG_KDB_KEYBOARD=y
Kernel Debugger Boot Arguments
==============================
This section describes the various runtime kernel parameters that affect
the configuration of the kernel debugger. The following chapter covers
using kdb and kgdb as well as providing some examples of the
configuration parameters.
Kernel parameter: kgdboc
------------------------
The kgdboc driver was originally an abbreviation meant to stand for
"kgdb over console". Today it is the primary mechanism to configure how
to communicate from gdb to kgdb as well as the devices you want to use
to interact with the kdb shell.
For kgdb/gdb, kgdboc is designed to work with a single serial port. It
is intended to cover the circumstance where you want to use a serial
console as your primary console as well as using it to perform kernel
debugging. It is also possible to use kgdb on a serial port which is not
designated as a system console. Kgdboc may be configured as a kernel
built-in or a kernel loadable module. You can only make use of
``kgdbwait`` and early debugging if you build kgdboc into the kernel as
a built-in.
Optionally you can elect to activate kms (Kernel Mode Setting)
integration. When you use kms with kgdboc and you have a video driver
that has atomic mode setting hooks, it is possible to enter the debugger
on the graphics console. When the kernel execution is resumed, the
previous graphics mode will be restored. This integration can serve as a
useful tool to aid in diagnosing crashes or doing analysis of memory
with kdb while allowing the full graphics console applications to run.
kgdboc arguments
~~~~~~~~~~~~~~~~
Usage::
kgdboc=[kms][[,]kbd][[,]serial_device][,baud]
The order listed above must be observed if you use any of the optional
configurations together.
Abbreviations:
- kms = Kernel Mode Setting
- kbd = Keyboard
You can configure kgdboc to use the keyboard, and/or a serial device
depending on if you are using kdb and/or kgdb, in one of the following
scenarios. The order listed above must be observed if you use any of the
optional configurations together. Using kms + only gdb is generally not
a useful combination.
Using loadable module or built-in
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. As a kernel built-in:
Use the kernel boot argument::
kgdboc=<tty-device>,[baud]
2. As a kernel loadable module:
Use the command::
modprobe kgdboc kgdboc=<tty-device>,[baud]
Here are two examples of how you might format the kgdboc string. The
first is for an x86 target using the first serial port. The second
example is for the ARM Versatile AB using the second serial port.
1. ``kgdboc=ttyS0,115200``
2. ``kgdboc=ttyAMA1,115200``
Configure kgdboc at runtime with sysfs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
At run time you can enable or disable kgdboc by echoing a parameters
into the sysfs. Here are two examples:
1. Enable kgdboc on ttyS0::
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
2. Disable kgdboc::
echo "" > /sys/module/kgdboc/parameters/kgdboc
.. note::
You do not need to specify the baud if you are configuring the
console on tty which is already configured or open.
More examples
^^^^^^^^^^^^^
You can configure kgdboc to use the keyboard, and/or a serial device
depending on if you are using kdb and/or kgdb, in one of the following
scenarios.
1. kdb and kgdb over only a serial port::
kgdboc=<serial_device>[,baud]
Example::
kgdboc=ttyS0,115200
2. kdb and kgdb with keyboard and a serial port::
kgdboc=kbd,<serial_device>[,baud]
Example::
kgdboc=kbd,ttyS0,115200
3. kdb with a keyboard::
kgdboc=kbd
4. kdb with kernel mode setting::
kgdboc=kms,kbd
5. kdb with kernel mode setting and kgdb over a serial port::
kgdboc=kms,kbd,ttyS0,115200
.. note::
Kgdboc does not support interrupting the target via the gdb remote
protocol. You must manually send a :kbd:`SysRq-G` unless you have a proxy
that splits console output to a terminal program. A console proxy has a
separate TCP port for the debugger and a separate TCP port for the
"human" console. The proxy can take care of sending the :kbd:`SysRq-G`
for you.
When using kgdboc with no debugger proxy, you can end up connecting the
debugger at one of two entry points. If an exception occurs after you
have loaded kgdboc, a message should print on the console stating it is
waiting for the debugger. In this case you disconnect your terminal
program and then connect the debugger in its place. If you want to
interrupt the target system and forcibly enter a debug session you have
to issue a :kbd:`Sysrq` sequence and then type the letter :kbd:`g`. Then you
disconnect the terminal session and connect gdb. Your options if you
don't like this are to hack gdb to send the :kbd:`SysRq-G` for you as well as
on the initial connect, or to use a debugger proxy that allows an
unmodified gdb to do the debugging.
Kernel parameter: ``kgdbwait``
------------------------------
The Kernel command line option ``kgdbwait`` makes kgdb wait for a
debugger connection during booting of a kernel. You can only use this
option if you compiled a kgdb I/O driver into the kernel and you
specified the I/O driver configuration as a kernel command line option.
The kgdbwait parameter should always follow the configuration parameter
for the kgdb I/O driver in the kernel command line else the I/O driver
will not be configured prior to asking the kernel to use it to wait.
The kernel will stop and wait as early as the I/O driver and
architecture allows when you use this option. If you build the kgdb I/O
driver as a loadable kernel module kgdbwait will not do anything.
Kernel parameter: ``kgdbcon``
-----------------------------
The ``kgdbcon`` feature allows you to see :c:func:`printk` messages inside gdb
while gdb is connected to the kernel. Kdb does not make use of the kgdbcon
feature.
Kgdb supports using the gdb serial protocol to send console messages to
the debugger when the debugger is connected and running. There are two
ways to activate this feature.
1. Activate with the kernel command line option::
kgdbcon
2. Use sysfs before configuring an I/O driver::
echo 1 > /sys/module/kgdb/parameters/kgdb_use_con
.. note::
If you do this after you configure the kgdb I/O driver, the
setting will not take effect until the next point the I/O is
reconfigured.
.. important::
You cannot use kgdboc + kgdbcon on a tty that is an
active system console. An example of incorrect usage is::
console=ttyS0,115200 kgdboc=ttyS0 kgdbcon
It is possible to use this option with kgdboc on a tty that is not a
system console.
Run time parameter: ``kgdbreboot``
----------------------------------
The kgdbreboot feature allows you to change how the debugger deals with
the reboot notification. You have 3 choices for the behavior. The
default behavior is always set to 0.
.. tabularcolumns:: |p{0.4cm}|p{11.5cm}|p{5.6cm}|
.. flat-table::
:widths: 1 10 8
* - 1
- ``echo -1 > /sys/module/debug_core/parameters/kgdbreboot``
- Ignore the reboot notification entirely.
* - 2
- ``echo 0 > /sys/module/debug_core/parameters/kgdbreboot``
- Send the detach message to any attached debugger client.
* - 3
- ``echo 1 > /sys/module/debug_core/parameters/kgdbreboot``
- Enter the debugger on reboot notify.
Kernel parameter: ``nokaslr``
-----------------------------
If the architecture that you are using enable KASLR by default,
you should consider turning it off. KASLR randomizes the
virtual address where the kernel image is mapped and confuse
gdb which resolve kernel symbol address from symbol table
of vmlinux.
Using kdb
=========
Quick start for kdb on a serial port
------------------------------------
This is a quick example of how to use kdb.
1. Configure kgdboc at boot using kernel parameters::
console=ttyS0,115200 kgdboc=ttyS0,115200 nokaslr
OR
Configure kgdboc after the kernel has booted; assuming you are using
a serial port console::
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
2. Enter the kernel debugger manually or by waiting for an oops or
fault. There are several ways you can enter the kernel debugger
manually; all involve using the :kbd:`SysRq-G`, which means you must have
enabled ``CONFIG_MAGIC_SysRq=y`` in your kernel config.
- When logged in as root or with a super user session you can run::
echo g > /proc/sysrq-trigger
- Example using minicom 2.2
Press: :kbd:`CTRL-A` :kbd:`f` :kbd:`g`
- When you have telneted to a terminal server that supports sending
a remote break
Press: :kbd:`CTRL-]`
Type in: ``send break``
Press: :kbd:`Enter` :kbd:`g`
3. From the kdb prompt you can run the ``help`` command to see a complete
list of the commands that are available.
Some useful commands in kdb include:
=========== =================================================================
``lsmod`` Shows where kernel modules are loaded
``ps`` Displays only the active processes
``ps A`` Shows all the processes
``summary`` Shows kernel version info and memory usage
``bt`` Get a backtrace of the current process using :c:func:`dump_stack`
``dmesg`` View the kernel syslog buffer
``go`` Continue the system
=========== =================================================================
4. When you are done using kdb you need to consider rebooting the system
or using the ``go`` command to resuming normal kernel execution. If you
have paused the kernel for a lengthy period of time, applications
that rely on timely networking or anything to do with real wall clock
time could be adversely affected, so you should take this into
consideration when using the kernel debugger.
Quick start for kdb using a keyboard connected console
------------------------------------------------------
This is a quick example of how to use kdb with a keyboard.
1. Configure kgdboc at boot using kernel parameters::
kgdboc=kbd
OR
Configure kgdboc after the kernel has booted::
echo kbd > /sys/module/kgdboc/parameters/kgdboc
2. Enter the kernel debugger manually or by waiting for an oops or
fault. There are several ways you can enter the kernel debugger
manually; all involve using the :kbd:`SysRq-G`, which means you must have
enabled ``CONFIG_MAGIC_SysRq=y`` in your kernel config.
- When logged in as root or with a super user session you can run::
echo g > /proc/sysrq-trigger
- Example using a laptop keyboard:
Press and hold down: :kbd:`Alt`
Press and hold down: :kbd:`Fn`
Press and release the key with the label: :kbd:`SysRq`
Release: :kbd:`Fn`
Press and release: :kbd:`g`
Release: :kbd:`Alt`
- Example using a PS/2 101-key keyboard
Press and hold down: :kbd:`Alt`
Press and release the key with the label: :kbd:`SysRq`
Press and release: :kbd:`g`
Release: :kbd:`Alt`
3. Now type in a kdb command such as ``help``, ``dmesg``, ``bt`` or ``go`` to
continue kernel execution.
Using kgdb / gdb
================
In order to use kgdb you must activate it by passing configuration
information to one of the kgdb I/O drivers. If you do not pass any
configuration information kgdb will not do anything at all. Kgdb will
only actively hook up to the kernel trap hooks if a kgdb I/O driver is
loaded and configured. If you unconfigure a kgdb I/O driver, kgdb will
unregister all the kernel hook points.
All kgdb I/O drivers can be reconfigured at run time, if
``CONFIG_SYSFS`` and ``CONFIG_MODULES`` are enabled, by echo'ing a new
config string to ``/sys/module/<driver>/parameter/<option>``. The driver
can be unconfigured by passing an empty string. You cannot change the
configuration while the debugger is attached. Make sure to detach the
debugger with the ``detach`` command prior to trying to unconfigure a
kgdb I/O driver.
Connecting with gdb to a serial port
------------------------------------
1. Configure kgdboc
Configure kgdboc at boot using kernel parameters::
kgdboc=ttyS0,115200
OR
Configure kgdboc after the kernel has booted::
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
2. Stop kernel execution (break into the debugger)
In order to connect to gdb via kgdboc, the kernel must first be
stopped. There are several ways to stop the kernel which include
using kgdbwait as a boot argument, via a :kbd:`SysRq-G`, or running the
kernel until it takes an exception where it waits for the debugger to
attach.
- When logged in as root or with a super user session you can run::
echo g > /proc/sysrq-trigger
- Example using minicom 2.2
Press: :kbd:`CTRL-A` :kbd:`f` :kbd:`g`
- When you have telneted to a terminal server that supports sending
a remote break
Press: :kbd:`CTRL-]`
Type in: ``send break``
Press: :kbd:`Enter` :kbd:`g`
3. Connect from gdb
Example (using a directly connected port)::
% gdb ./vmlinux
(gdb) set remotebaud 115200
(gdb) target remote /dev/ttyS0
Example (kgdb to a terminal server on TCP port 2012)::
% gdb ./vmlinux
(gdb) target remote 192.168.2.2:2012
Once connected, you can debug a kernel the way you would debug an
application program.
If you are having problems connecting or something is going seriously
wrong while debugging, it will most often be the case that you want
to enable gdb to be verbose about its target communications. You do
this prior to issuing the ``target remote`` command by typing in::
set debug remote 1
Remember if you continue in gdb, and need to "break in" again, you need
to issue an other :kbd:`SysRq-G`. It is easy to create a simple entry point by
putting a breakpoint at ``sys_sync`` and then you can run ``sync`` from a
shell or script to break into the debugger.
kgdb and kdb interoperability
=============================
It is possible to transition between kdb and kgdb dynamically. The debug
core will remember which you used the last time and automatically start
in the same mode.
Switching between kdb and kgdb
------------------------------
Switching from kgdb to kdb
~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two ways to switch from kgdb to kdb: you can use gdb to issue
a maintenance packet, or you can blindly type the command ``$3#33``.
Whenever the kernel debugger stops in kgdb mode it will print the
message ``KGDB or $3#33 for KDB``. It is important to note that you have
to type the sequence correctly in one pass. You cannot type a backspace
or delete because kgdb will interpret that as part of the debug stream.
1. Change from kgdb to kdb by blindly typing::
$3#33
2. Change from kgdb to kdb with gdb::
maintenance packet 3
.. note::
Now you must kill gdb. Typically you press :kbd:`CTRL-Z` and issue
the command::
kill -9 %
Change from kdb to kgdb
~~~~~~~~~~~~~~~~~~~~~~~
There are two ways you can change from kdb to kgdb. You can manually
enter kgdb mode by issuing the kgdb command from the kdb shell prompt,
or you can connect gdb while the kdb shell prompt is active. The kdb
shell looks for the typical first commands that gdb would issue with the
gdb remote protocol and if it sees one of those commands it
automatically changes into kgdb mode.
1. From kdb issue the command::
kgdb
Now disconnect your terminal program and connect gdb in its place
2. At the kdb prompt, disconnect the terminal program and connect gdb in
its place.
Running kdb commands from gdb
-----------------------------
It is possible to run a limited set of kdb commands from gdb, using the
gdb monitor command. You don't want to execute any of the run control or
breakpoint operations, because it can disrupt the state of the kernel
debugger. You should be using gdb for breakpoints and run control
operations if you have gdb connected. The more useful commands to run
are things like lsmod, dmesg, ps or possibly some of the memory
information commands. To see all the kdb commands you can run
``monitor help``.
Example::
(gdb) monitor ps
1 idle process (state I) and
27 sleeping system daemon (state M) processes suppressed,
use 'ps A' to see all.
Task Addr Pid Parent [*] cpu State Thread Command
0xc78291d0 1 0 0 0 S 0xc7829404 init
0xc7954150 942 1 0 0 S 0xc7954384 dropbear
0xc78789c0 944 1 0 0 S 0xc7878bf4 sh
(gdb)
kgdb Test Suite
===============
When kgdb is enabled in the kernel config you can also elect to enable
the config parameter ``KGDB_TESTS``. Turning this on will enable a special
kgdb I/O module which is designed to test the kgdb internal functions.
The kgdb tests are mainly intended for developers to test the kgdb
internals as well as a tool for developing a new kgdb architecture
specific implementation. These tests are not really for end users of the
Linux kernel. The primary source of documentation would be to look in
the ``drivers/misc/kgdbts.c`` file.
The kgdb test suite can also be configured at compile time to run the
core set of tests by setting the kernel config parameter
``KGDB_TESTS_ON_BOOT``. This particular option is aimed at automated
regression testing and does not require modifying the kernel boot config
arguments. If this is turned on, the kgdb test suite can be disabled by
specifying ``kgdbts=`` as a kernel boot argument.
Kernel Debugger Internals
=========================
Architecture Specifics
----------------------
The kernel debugger is organized into a number of components:
1. The debug core
The debug core is found in ``kernel/debugger/debug_core.c``. It
contains:
- A generic OS exception handler which includes sync'ing the
processors into a stopped state on an multi-CPU system.
- The API to talk to the kgdb I/O drivers
- The API to make calls to the arch-specific kgdb implementation
- The logic to perform safe memory reads and writes to memory while
using the debugger
- A full implementation for software breakpoints unless overridden
by the arch
- The API to invoke either the kdb or kgdb frontend to the debug
core.
- The structures and callback API for atomic kernel mode setting.
.. note:: kgdboc is where the kms callbacks are invoked.
2. kgdb arch-specific implementation
This implementation is generally found in ``arch/*/kernel/kgdb.c``. As
an example, ``arch/x86/kernel/kgdb.c`` contains the specifics to
implement HW breakpoint as well as the initialization to dynamically
register and unregister for the trap handlers on this architecture.
The arch-specific portion implements:
- contains an arch-specific trap catcher which invokes
:c:func:`kgdb_handle_exception` to start kgdb about doing its work
- translation to and from gdb specific packet format to :c:type:`pt_regs`
- Registration and unregistration of architecture specific trap
hooks
- Any special exception handling and cleanup
- NMI exception handling and cleanup
- (optional) HW breakpoints
3. gdbstub frontend (aka kgdb)
The gdbstub is located in ``kernel/debug/gdbstub.c``. It contains:
- All the logic to implement the gdb serial protocol
4. kdb frontend
The kdb debugger shell is broken down into a number of components.
The kdb core is located in kernel/debug/kdb. There are a number of
helper functions in some of the other kernel components to make it
possible for kdb to examine and report information about the kernel
without taking locks that could cause a kernel deadlock. The kdb core
contains implements the following functionality.
- A simple shell
- The kdb core command set
- A registration API to register additional kdb shell commands.
- A good example of a self-contained kdb module is the ``ftdump``
command for dumping the ftrace buffer. See:
``kernel/trace/trace_kdb.c``
- For an example of how to dynamically register a new kdb command
you can build the kdb_hello.ko kernel module from
``samples/kdb/kdb_hello.c``. To build this example you can set
``CONFIG_SAMPLES=y`` and ``CONFIG_SAMPLE_KDB=m`` in your kernel
config. Later run ``modprobe kdb_hello`` and the next time you
enter the kdb shell, you can run the ``hello`` command.
- The implementation for :c:func:`kdb_printf` which emits messages directly
to I/O drivers, bypassing the kernel log.
- SW / HW breakpoint management for the kdb shell
5. kgdb I/O driver
Each kgdb I/O driver has to provide an implementation for the
following:
- configuration via built-in or module
- dynamic configuration and kgdb hook registration calls
- read and write character interface
- A cleanup handler for unconfiguring from the kgdb core
- (optional) Early debug methodology
Any given kgdb I/O driver has to operate very closely with the
hardware and must do it in such a way that does not enable interrupts
or change other parts of the system context without completely
restoring them. The kgdb core will repeatedly "poll" a kgdb I/O
driver for characters when it needs input. The I/O driver is expected
to return immediately if there is no data available. Doing so allows
for the future possibility to touch watchdog hardware in such a way
as to have a target system not reset when these are enabled.
If you are intent on adding kgdb architecture specific support for a new
architecture, the architecture should define ``HAVE_ARCH_KGDB`` in the
architecture specific Kconfig file. This will enable kgdb for the
architecture, and at that point you must create an architecture specific
kgdb implementation.
There are a few flags which must be set on every architecture in their
``asm/kgdb.h`` file. These are:
- ``NUMREGBYTES``:
The size in bytes of all of the registers, so that we
can ensure they will all fit into a packet.
- ``BUFMAX``:
The size in bytes of the buffer GDB will read into. This must
be larger than NUMREGBYTES.
- ``CACHE_FLUSH_IS_SAFE``:
Set to 1 if it is always safe to call
flush_cache_range or flush_icache_range. On some architectures,
these functions may not be safe to call on SMP since we keep other
CPUs in a holding pattern.
There are also the following functions for the common backend, found in
``kernel/kgdb.c``, that must be supplied by the architecture-specific
backend unless marked as (optional), in which case a default function
maybe used if the architecture does not need to provide a specific
implementation.
.. kernel-doc:: include/linux/kgdb.h
:internal:
kgdboc internals
----------------
kgdboc and uarts
~~~~~~~~~~~~~~~~
The kgdboc driver is actually a very thin driver that relies on the
underlying low level to the hardware driver having "polling hooks" to
which the tty driver is attached. In the initial implementation of
kgdboc the serial_core was changed to expose a low level UART hook for
doing polled mode reading and writing of a single character while in an
atomic context. When kgdb makes an I/O request to the debugger, kgdboc
invokes a callback in the serial core which in turn uses the callback in
the UART driver.
When using kgdboc with a UART, the UART driver must implement two
callbacks in the :c:type:`struct uart_ops <uart_ops>`.
Example from ``drivers/8250.c``::
#ifdef CONFIG_CONSOLE_POLL
.poll_get_char = serial8250_get_poll_char,
.poll_put_char = serial8250_put_poll_char,
#endif
Any implementation specifics around creating a polling driver use the
``#ifdef CONFIG_CONSOLE_POLL``, as shown above. Keep in mind that
polling hooks have to be implemented in such a way that they can be
called from an atomic context and have to restore the state of the UART
chip on return such that the system can return to normal when the
debugger detaches. You need to be very careful with any kind of lock you
consider, because failing here is most likely going to mean pressing the
reset button.
kgdboc and keyboards
~~~~~~~~~~~~~~~~~~~~~~~~
The kgdboc driver contains logic to configure communications with an
attached keyboard. The keyboard infrastructure is only compiled into the
kernel when ``CONFIG_KDB_KEYBOARD=y`` is set in the kernel configuration.
The core polled keyboard driver driver for PS/2 type keyboards is in
``drivers/char/kdb_keyboard.c``. This driver is hooked into the debug core
when kgdboc populates the callback in the array called
:c:type:`kdb_poll_funcs[]`. The :c:func:`kdb_get_kbd_char` is the top-level
function which polls hardware for single character input.
kgdboc and kms
~~~~~~~~~~~~~~~~~~
The kgdboc driver contains logic to request the graphics display to
switch to a text context when you are using ``kgdboc=kms,kbd``, provided
that you have a video driver which has a frame buffer console and atomic
kernel mode setting support.
Every time the kernel debugger is entered it calls
:c:func:`kgdboc_pre_exp_handler` which in turn calls :c:func:`con_debug_enter`
in the virtual console layer. On resuming kernel execution, the kernel
debugger calls :c:func:`kgdboc_post_exp_handler` which in turn calls
:c:func:`con_debug_leave`.
Any video driver that wants to be compatible with the kernel debugger
and the atomic kms callbacks must implement the ``mode_set_base_atomic``,
``fb_debug_enter`` and ``fb_debug_leave operations``. For the
``fb_debug_enter`` and ``fb_debug_leave`` the option exists to use the
generic drm fb helper functions or implement something custom for the
hardware. The following example shows the initialization of the
.mode_set_base_atomic operation in
drivers/gpu/drm/i915/intel_display.c::
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
[...]
.mode_set_base_atomic = intel_pipe_set_base_atomic,
[...]
};
Here is an example of how the i915 driver initializes the
fb_debug_enter and fb_debug_leave functions to use the generic drm
helpers in ``drivers/gpu/drm/i915/intel_fb.c``::
static struct fb_ops intelfb_ops = {
[...]
.fb_debug_enter = drm_fb_helper_debug_enter,
.fb_debug_leave = drm_fb_helper_debug_leave,
[...]
};
Credits
=======
The following people have contributed to this document:
1. Amit Kale <amitkale@linsyssoft.com>
2. Tom Rini <trini@kernel.crashing.org>
In March 2008 this document was completely rewritten by:
- Jason Wessel <jason.wessel@windriver.com>
In Jan 2010 this document was updated to include kdb.
- Jason Wessel <jason.wessel@windriver.com>
+220
View File
@@ -0,0 +1,220 @@
Kernel Memory Leak Detector
===========================
Kmemleak provides a way of detecting possible kernel memory leaks in a
way similar to a tracing garbage collector
(https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Tracing_garbage_collectors),
with the difference that the orphan objects are not freed but only
reported via /sys/kernel/debug/kmemleak. A similar method is used by the
Valgrind tool (``memcheck --leak-check``) to detect the memory leaks in
user-space applications.
Kmemleak is supported on x86, arm, powerpc, sparc, sh, microblaze, ppc, mips, s390 and tile.
Usage
-----
CONFIG_DEBUG_KMEMLEAK in "Kernel hacking" has to be enabled. A kernel
thread scans the memory every 10 minutes (by default) and prints the
number of new unreferenced objects found. To display the details of all
the possible memory leaks::
# mount -t debugfs nodev /sys/kernel/debug/
# cat /sys/kernel/debug/kmemleak
To trigger an intermediate memory scan::
# echo scan > /sys/kernel/debug/kmemleak
To clear the list of all current possible memory leaks::
# echo clear > /sys/kernel/debug/kmemleak
New leaks will then come up upon reading ``/sys/kernel/debug/kmemleak``
again.
Note that the orphan objects are listed in the order they were allocated
and one object at the beginning of the list may cause other subsequent
objects to be reported as orphan.
Memory scanning parameters can be modified at run-time by writing to the
``/sys/kernel/debug/kmemleak`` file. The following parameters are supported:
- off
disable kmemleak (irreversible)
- stack=on
enable the task stacks scanning (default)
- stack=off
disable the tasks stacks scanning
- scan=on
start the automatic memory scanning thread (default)
- scan=off
stop the automatic memory scanning thread
- scan=<secs>
set the automatic memory scanning period in seconds
(default 600, 0 to stop the automatic scanning)
- scan
trigger a memory scan
- clear
clear list of current memory leak suspects, done by
marking all current reported unreferenced objects grey,
or free all kmemleak objects if kmemleak has been disabled.
- dump=<addr>
dump information about the object found at <addr>
Kmemleak can also be disabled at boot-time by passing ``kmemleak=off`` on
the kernel command line.
Memory may be allocated or freed before kmemleak is initialised and
these actions are stored in an early log buffer. The size of this buffer
is configured via the CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE option.
If CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF are enabled, the kmemleak is
disabled by default. Passing ``kmemleak=on`` on the kernel command
line enables the function.
Basic Algorithm
---------------
The memory allocations via :c:func:`kmalloc`, :c:func:`vmalloc`,
:c:func:`kmem_cache_alloc` and
friends are traced and the pointers, together with additional
information like size and stack trace, are stored in a rbtree.
The corresponding freeing function calls are tracked and the pointers
removed from the kmemleak data structures.
An allocated block of memory is considered orphan if no pointer to its
start address or to any location inside the block can be found by
scanning the memory (including saved registers). This means that there
might be no way for the kernel to pass the address of the allocated
block to a freeing function and therefore the block is considered a
memory leak.
The scanning algorithm steps:
1. mark all objects as white (remaining white objects will later be
considered orphan)
2. scan the memory starting with the data section and stacks, checking
the values against the addresses stored in the rbtree. If
a pointer to a white object is found, the object is added to the
gray list
3. scan the gray objects for matching addresses (some white objects
can become gray and added at the end of the gray list) until the
gray set is finished
4. the remaining white objects are considered orphan and reported via
/sys/kernel/debug/kmemleak
Some allocated memory blocks have pointers stored in the kernel's
internal data structures and they cannot be detected as orphans. To
avoid this, kmemleak can also store the number of values pointing to an
address inside the block address range that need to be found so that the
block is not considered a leak. One example is __vmalloc().
Testing specific sections with kmemleak
---------------------------------------
Upon initial bootup your /sys/kernel/debug/kmemleak output page may be
quite extensive. This can also be the case if you have very buggy code
when doing development. To work around these situations you can use the
'clear' command to clear all reported unreferenced objects from the
/sys/kernel/debug/kmemleak output. By issuing a 'scan' after a 'clear'
you can find new unreferenced objects; this should help with testing
specific sections of code.
To test a critical section on demand with a clean kmemleak do::
# echo clear > /sys/kernel/debug/kmemleak
... test your kernel or modules ...
# echo scan > /sys/kernel/debug/kmemleak
Then as usual to get your report with::
# cat /sys/kernel/debug/kmemleak
Freeing kmemleak internal objects
---------------------------------
To allow access to previously found memory leaks after kmemleak has been
disabled by the user or due to an fatal error, internal kmemleak objects
won't be freed when kmemleak is disabled, and those objects may occupy
a large part of physical memory.
In this situation, you may reclaim memory with::
# echo clear > /sys/kernel/debug/kmemleak
Kmemleak API
------------
See the include/linux/kmemleak.h header for the functions prototype.
- ``kmemleak_init`` - initialize kmemleak
- ``kmemleak_alloc`` - notify of a memory block allocation
- ``kmemleak_alloc_percpu`` - notify of a percpu memory block allocation
- ``kmemleak_vmalloc`` - notify of a vmalloc() memory allocation
- ``kmemleak_free`` - notify of a memory block freeing
- ``kmemleak_free_part`` - notify of a partial memory block freeing
- ``kmemleak_free_percpu`` - notify of a percpu memory block freeing
- ``kmemleak_update_trace`` - update object allocation stack trace
- ``kmemleak_not_leak`` - mark an object as not a leak
- ``kmemleak_ignore`` - do not scan or report an object as leak
- ``kmemleak_scan_area`` - add scan areas inside a memory block
- ``kmemleak_no_scan`` - do not scan a memory block
- ``kmemleak_erase`` - erase an old value in a pointer variable
- ``kmemleak_alloc_recursive`` - as kmemleak_alloc but checks the recursiveness
- ``kmemleak_free_recursive`` - as kmemleak_free but checks the recursiveness
The following functions take a physical address as the object pointer
and only perform the corresponding action if the address has a lowmem
mapping:
- ``kmemleak_alloc_phys``
- ``kmemleak_free_part_phys``
- ``kmemleak_not_leak_phys``
- ``kmemleak_ignore_phys``
Dealing with false positives/negatives
--------------------------------------
The false negatives are real memory leaks (orphan objects) but not
reported by kmemleak because values found during the memory scanning
point to such objects. To reduce the number of false negatives, kmemleak
provides the kmemleak_ignore, kmemleak_scan_area, kmemleak_no_scan and
kmemleak_erase functions (see above). The task stacks also increase the
amount of false negatives and their scanning is not enabled by default.
The false positives are objects wrongly reported as being memory leaks
(orphan). For objects known not to be leaks, kmemleak provides the
kmemleak_not_leak function. The kmemleak_ignore could also be used if
the memory block is known not to contain other pointers and it will no
longer be scanned.
Some of the reported leaks are only transient, especially on SMP
systems, because of pointers temporarily stored in CPU registers or
stacks. Kmemleak defines MSECS_MIN_AGE (defaulting to 1000) representing
the minimum age of an object to be reported as a memory leak.
Limitations and Drawbacks
-------------------------
The main drawback is the reduced performance of memory allocation and
freeing. To avoid other penalties, the memory scanning is only performed
when the /sys/kernel/debug/kmemleak file is read. Anyway, this tool is
intended for debugging purposes where the performance might not be the
most important requirement.
To keep the algorithm simple, kmemleak scans for values pointing to any
address inside a block's address range. This may lead to an increased
number of false negatives. However, it is likely that a real memory leak
will eventually become visible.
Another source of false negatives is the data stored in non-pointer
values. In a future version, kmemleak could only scan the pointer
members in the allocated structures. This feature would solve many of
the false negative cases described above.
The tool can report false positives. These are cases where an allocated
block doesn't need to be freed (some cases in the init_call functions),
the pointer is calculated by other methods than the usual container_of
macro or the pointer is stored in a location not scanned by kmemleak.
Page allocations and ioremap are not tracked.
+195
View File
@@ -0,0 +1,195 @@
======================
Linux Kernel Selftests
======================
The kernel contains a set of "self tests" under the tools/testing/selftests/
directory. These are intended to be small tests to exercise individual code
paths in the kernel. Tests are intended to be run after building, installing
and booting a kernel.
On some systems, hot-plug tests could hang forever waiting for cpu and
memory to be ready to be offlined. A special hot-plug target is created
to run full range of hot-plug tests. In default mode, hot-plug tests run
in safe mode with a limited scope. In limited mode, cpu-hotplug test is
run on a single cpu as opposed to all hotplug capable cpus, and memory
hotplug test is run on 2% of hotplug capable memory instead of 10%.
Running the selftests (hotplug tests are run in limited mode)
=============================================================
To build the tests::
$ make -C tools/testing/selftests
To run the tests::
$ make -C tools/testing/selftests run_tests
To build and run the tests with a single command, use::
$ make kselftest
Note that some tests will require root privileges.
Build and run from user specific object directory (make O=dir)::
$ make O=/tmp/kselftest kselftest
Build and run KBUILD_OUTPUT directory (make KBUILD_OUTPUT=)::
$ make KBUILD_OUTPUT=/tmp/kselftest kselftest
The above commands run the tests and print pass/fail summary to make it
easier to understand the test results. Please find the detailed individual
test results for each test in /tmp/testname file(s).
Running a subset of selftests
=============================
You can use the "TARGETS" variable on the make command line to specify
single test to run, or a list of tests to run.
To run only tests targeted for a single subsystem::
$ make -C tools/testing/selftests TARGETS=ptrace run_tests
You can specify multiple tests to build and run::
$ make TARGETS="size timers" kselftest
Build and run from user specific object directory (make O=dir)::
$ make O=/tmp/kselftest TARGETS="size timers" kselftest
Build and run KBUILD_OUTPUT directory (make KBUILD_OUTPUT=)::
$ make KBUILD_OUTPUT=/tmp/kselftest TARGETS="size timers" kselftest
The above commands run the tests and print pass/fail summary to make it
easier to understand the test results. Please find the detailed individual
test results for each test in /tmp/testname file(s).
See the top-level tools/testing/selftests/Makefile for the list of all
possible targets.
Running the full range hotplug selftests
========================================
To build the hotplug tests::
$ make -C tools/testing/selftests hotplug
To run the hotplug tests::
$ make -C tools/testing/selftests run_hotplug
Note that some tests will require root privileges.
Install selftests
=================
You can use kselftest_install.sh tool installs selftests in default
location which is tools/testing/selftests/kselftest or a user specified
location.
To install selftests in default location::
$ cd tools/testing/selftests
$ ./kselftest_install.sh
To install selftests in a user specified location::
$ cd tools/testing/selftests
$ ./kselftest_install.sh install_dir
Running installed selftests
===========================
Kselftest install as well as the Kselftest tarball provide a script
named "run_kselftest.sh" to run the tests.
You can simply do the following to run the installed Kselftests. Please
note some tests will require root privileges::
$ cd kselftest
$ ./run_kselftest.sh
Contributing new tests
======================
In general, the rules for selftests are
* Do as much as you can if you're not root;
* Don't take too long;
* Don't break the build on any architecture, and
* Don't cause the top-level "make run_tests" to fail if your feature is
unconfigured.
Contributing new tests (details)
================================
* Use TEST_GEN_XXX if such binaries or files are generated during
compiling.
TEST_PROGS, TEST_GEN_PROGS mean it is the executable tested by
default.
TEST_CUSTOM_PROGS should be used by tests that require custom build
rule and prevent common build rule use.
TEST_PROGS are for test shell scripts. Please ensure shell script has
its exec bit set. Otherwise, lib.mk run_tests will generate a warning.
TEST_CUSTOM_PROGS and TEST_PROGS will be run by common run_tests.
TEST_PROGS_EXTENDED, TEST_GEN_PROGS_EXTENDED mean it is the
executable which is not tested by default.
TEST_FILES, TEST_GEN_FILES mean it is the file which is used by
test.
* First use the headers inside the kernel source and/or git repo, and then the
system headers. Headers for the kernel release as opposed to headers
installed by the distro on the system should be the primary focus to be able
to find regressions.
* If a test needs specific kernel config options enabled, add a config file in
the test directory to enable them.
e.g: tools/testing/selftests/android/ion/config
Test Harness
============
The kselftest_harness.h file contains useful helpers to build tests. The tests
from tools/testing/selftests/seccomp/seccomp_bpf.c can be used as example.
Example
-------
.. kernel-doc:: tools/testing/selftests/kselftest_harness.h
:doc: example
Helpers
-------
.. kernel-doc:: tools/testing/selftests/kselftest_harness.h
:functions: TH_LOG TEST TEST_SIGNAL FIXTURE FIXTURE_DATA FIXTURE_SETUP
FIXTURE_TEARDOWN TEST_F TEST_HARNESS_MAIN
Operators
---------
.. kernel-doc:: tools/testing/selftests/kselftest_harness.h
:doc: operators
.. kernel-doc:: tools/testing/selftests/kselftest_harness.h
:functions: ASSERT_EQ ASSERT_NE ASSERT_LT ASSERT_LE ASSERT_GT ASSERT_GE
ASSERT_NULL ASSERT_TRUE ASSERT_NULL ASSERT_TRUE ASSERT_FALSE
ASSERT_STREQ ASSERT_STRNE EXPECT_EQ EXPECT_NE EXPECT_LT
EXPECT_LE EXPECT_GT EXPECT_GE EXPECT_NULL EXPECT_TRUE
EXPECT_FALSE EXPECT_STREQ EXPECT_STRNE
+105
View File
@@ -0,0 +1,105 @@
.. Copyright 2004 Linus Torvalds
.. Copyright 2004 Pavel Machek <pavel@ucw.cz>
.. Copyright 2006 Bob Copeland <me@bobcopeland.com>
Sparse
======
Sparse is a semantic checker for C programs; it can be used to find a
number of potential problems with kernel code. See
https://lwn.net/Articles/689907/ for an overview of sparse; this document
contains some kernel-specific sparse information.
Using sparse for typechecking
-----------------------------
"__bitwise" is a type attribute, so you have to do something like this::
typedef int __bitwise pm_request_t;
enum pm_request {
PM_SUSPEND = (__force pm_request_t) 1,
PM_RESUME = (__force pm_request_t) 2
};
which makes PM_SUSPEND and PM_RESUME "bitwise" integers (the "__force" is
there because sparse will complain about casting to/from a bitwise type,
but in this case we really _do_ want to force the conversion). And because
the enum values are all the same type, now "enum pm_request" will be that
type too.
And with gcc, all the "__bitwise"/"__force stuff" goes away, and it all
ends up looking just like integers to gcc.
Quite frankly, you don't need the enum there. The above all really just
boils down to one special "int __bitwise" type.
So the simpler way is to just do::
typedef int __bitwise pm_request_t;
#define PM_SUSPEND ((__force pm_request_t) 1)
#define PM_RESUME ((__force pm_request_t) 2)
and you now have all the infrastructure needed for strict typechecking.
One small note: the constant integer "0" is special. You can use a
constant zero as a bitwise integer type without sparse ever complaining.
This is because "bitwise" (as the name implies) was designed for making
sure that bitwise types don't get mixed up (little-endian vs big-endian
vs cpu-endian vs whatever), and there the constant "0" really _is_
special.
Using sparse for lock checking
------------------------------
The following macros are undefined for gcc and defined during a sparse
run to use the "context" tracking feature of sparse, applied to
locking. These annotations tell sparse when a lock is held, with
regard to the annotated function's entry and exit.
__must_hold - The specified lock is held on function entry and exit.
__acquires - The specified lock is held on function exit, but not entry.
__releases - The specified lock is held on function entry, but not exit.
If the function enters and exits without the lock held, acquiring and
releasing the lock inside the function in a balanced way, no
annotation is needed. The three annotations above are for cases where
sparse would otherwise report a context imbalance.
Getting sparse
--------------
You can get latest released versions from the Sparse homepage at
https://sparse.wiki.kernel.org/index.php/Main_Page
Alternatively, you can get snapshots of the latest development version
of sparse using git to clone::
git://git.kernel.org/pub/scm/devel/sparse/sparse.git
DaveJ has hourly generated tarballs of the git tree available at::
http://www.codemonkey.org.uk/projects/git-snapshots/sparse/
Once you have it, just do::
make
make install
as a regular user, and it will install sparse in your ~/bin directory.
Using sparse
------------
Do a kernel make with "make C=1" to run sparse on all the C files that get
recompiled, or use "make C=2" to run sparse on the files whether they need to
be recompiled or not. The latter is a fast way to check the whole tree if you
have already built it.
The optional make variable CF can be used to pass arguments to sparse. The
build system passes -Wbitwise to sparse automatically.
+88
View File
@@ -0,0 +1,88 @@
The Undefined Behavior Sanitizer - UBSAN
========================================
UBSAN is a runtime undefined behaviour checker.
UBSAN uses compile-time instrumentation to catch undefined behavior (UB).
Compiler inserts code that perform certain kinds of checks before operations
that may cause UB. If check fails (i.e. UB detected) __ubsan_handle_*
function called to print error message.
GCC has that feature since 4.9.x [1_] (see ``-fsanitize=undefined`` option and
its suboptions). GCC 5.x has more checkers implemented [2_].
Report example
--------------
::
================================================================================
UBSAN: Undefined behaviour in ../include/linux/bitops.h:110:33
shift exponent 32 is to large for 32-bit type 'unsigned int'
CPU: 0 PID: 0 Comm: swapper Not tainted 4.4.0-rc1+ #26
0000000000000000 ffffffff82403cc8 ffffffff815e6cd6 0000000000000001
ffffffff82403cf8 ffffffff82403ce0 ffffffff8163a5ed 0000000000000020
ffffffff82403d78 ffffffff8163ac2b ffffffff815f0001 0000000000000002
Call Trace:
[<ffffffff815e6cd6>] dump_stack+0x45/0x5f
[<ffffffff8163a5ed>] ubsan_epilogue+0xd/0x40
[<ffffffff8163ac2b>] __ubsan_handle_shift_out_of_bounds+0xeb/0x130
[<ffffffff815f0001>] ? radix_tree_gang_lookup_slot+0x51/0x150
[<ffffffff8173c586>] _mix_pool_bytes+0x1e6/0x480
[<ffffffff83105653>] ? dmi_walk_early+0x48/0x5c
[<ffffffff8173c881>] add_device_randomness+0x61/0x130
[<ffffffff83105b35>] ? dmi_save_one_device+0xaa/0xaa
[<ffffffff83105653>] dmi_walk_early+0x48/0x5c
[<ffffffff831066ae>] dmi_scan_machine+0x278/0x4b4
[<ffffffff8111d58a>] ? vprintk_default+0x1a/0x20
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830b2240>] setup_arch+0x405/0xc2c
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ae053>] start_kernel+0x83/0x49a
[<ffffffff830ad120>] ? early_idt_handler_array+0x120/0x120
[<ffffffff830ad386>] x86_64_start_reservations+0x2a/0x2c
[<ffffffff830ad4f3>] x86_64_start_kernel+0x16b/0x17a
================================================================================
Usage
-----
To enable UBSAN configure kernel with::
CONFIG_UBSAN=y
and to check the entire kernel::
CONFIG_UBSAN_SANITIZE_ALL=y
To enable instrumentation for specific files or directories, add a line
similar to the following to the respective kernel Makefile:
- For a single file (e.g. main.o)::
UBSAN_SANITIZE_main.o := y
- For all files in one directory::
UBSAN_SANITIZE := y
To exclude files from being instrumented even if
``CONFIG_UBSAN_SANITIZE_ALL=y``, use::
UBSAN_SANITIZE_main.o := n
and::
UBSAN_SANITIZE := n
Detection of unaligned accesses controlled through the separate option -
CONFIG_UBSAN_ALIGNMENT. It's off by default on architectures that support
unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
still enable it in config, just note that it will produce a lot of UBSAN
reports.
References
----------
.. _1: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/gcc/Debugging-Options.html
.. _2: https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html