From: Johannes Berg <johannes.berg@xxxxxxxxx> The new --gdb option can be used when KERNELDIR (and optionally MODULEDIR) are set and we therefore run UML. It runs the entire VM under the debugger, with a script to load the right modules into gdb so you can debug easily. Signed-off-by: Johannes Berg <johannes.berg@xxxxxxxxx> --- tests/hwsim/vm/linux.gdb | 68 ++++++++++++++++++++++++++++++++++++++++ tests/hwsim/vm/vm-run.sh | 19 ++++++++--- 2 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/hwsim/vm/linux.gdb diff --git a/tests/hwsim/vm/linux.gdb b/tests/hwsim/vm/linux.gdb new file mode 100644 index 000000000000..539d73e5659d --- /dev/null +++ b/tests/hwsim/vm/linux.gdb @@ -0,0 +1,68 @@ +python +import os, subprocess +kdir = os.environ['KERNELDIR'] +mdir = os.environ['MODULEDIR'] or '/lib/modules' +gdb.execute(f'add-auto-load-safe-path {kdir}/scripts/gdb/') +cwd=os.getcwd() +gdb.execute(f'cd {kdir}') +gdb.execute(f'source {kdir}/vmlinux-gdb.py') +p = subprocess.run([f'./linux', '--version'], capture_output=True) +ver = p.stdout.strip().decode('ascii') +gdb.execute(f'cd {cwd}') +end +break os_early_checks +commands +silent +python +gdb.execute(f'cd {kdir}') +gdb.execute(f'lx-symbols {mdir}/{ver}/') +gdb.execute(f'cd {cwd}') +end +# only once +del 1 +continue +end +handle 11 nostop noprint pass +# +# So ... this is complicated. When gdb installs a regular breakpoint +# on some place, it writes there a breakpoint instruction (which is +# a single 0xCC byte on x86). This breaks out into the debugger and +# it can then restart/simulate the correct instruction when continuing +# across the breakpoint. +# +# Additionally, gdb (correctly) removes these breakpoint instructions +# from forked children when detaching from them. This also seems fine. +# +# However, due to how user-mode-linux works, this causes issues with +# kernel modules. These are loaded into the vmalloc area, and even if +# that isn't quite part of physmem, it's still mapped as MAP_SHARED. +# +# Unfortunately, this means that gdb deletes breakpoints in modules +# when a new userspace process is started, since that causes a new +# process to be created by clone() and gdb has to detach from it. +# +# The other thing to know is that when gdb hits a breakpoint it will +# restore all the code to normal, and reinstall breakpoints when we +# continue. +# +# Thus we can use that behaviour to work around the module issue: +# simply put a breakpoint on init_new_ldt which happens just after +# the clone() for a new userspace process, and do nothing there but +# continue, which reinstalls all breakpoints, including the ones in +# modules. +# +break init_new_ldt +commands +silent +continue +end + +echo \n +echo Welcome to hwsim kernel debugging\n +echo ---------------------------------\n\n +echo You can install breakpoints in modules, they're treated\n +echo as shared libraries, so just say 'y' if asked to make the\n +echo breakpoint pending on future load.\n\n +echo Do NOT, however, delete the breakpoint on 'init_new_ldt'!\n\n +echo Now enter 'run' to start the run.\n\n +echo Have fun!\n\n diff --git a/tests/hwsim/vm/vm-run.sh b/tests/hwsim/vm/vm-run.sh index defea43e8723..0978581b47f2 100755 --- a/tests/hwsim/vm/vm-run.sh +++ b/tests/hwsim/vm/vm-run.sh @@ -62,6 +62,7 @@ TIMESTAMP=$(date +%s) DATE=$TIMESTAMP CODECOV=no TIMEWARP=0 +GDB=0 TELNET_QEMU= TELNET_ARG=0 CODECOV_DIR= @@ -85,6 +86,9 @@ while [ "$1" != "" ]; do --timewrap ) shift TIMEWARP=1 ;; + --gdb ) shift + GDB=1 + ;; --telnet ) shift TELNET_ARG=1 TELNET_QEMU="-net nic,model=virtio -net user,id=telnet,restrict=on,net=172.16.0.0/24,hostfwd=tcp:127.0.0.1:$1-:23" @@ -162,17 +166,22 @@ fi A+="ro" if [ -z $KVM ]; then - $KERNEL \ - mem=${MEMORY}M \ + UML_ARGS="mem=${MEMORY}M \ LOGDIR=$LOGDIR \ time-travel=inf-cpu \ $A \ root=none hostfs=/ rootfstype=hostfs rootflags=/ \ ssl0=fd:0,fd:1 \ ssl1=fd:100 \ - ssl-non-raw \ - 100<>$LOGDIR/console 2>&1 | \ - sed -u '0,/VM has started up/d' + ssl-non-raw" + + if [ "$GDB" = "1" ] ; then + export KERNELDIR=$KERNELDIR + export MODULEDIR=$MODULEDIR + gdb -ex "source linux.gdb" --args $KERNEL $UML_ARGS 100<>$LOGDIR/console + else + $KERNEL $UML_ARGS 100<>$LOGDIR/console #2>&1 | sed -u '0,/VM has started up/d' + fi else $KVM \ -kernel $KERNEL \ -- 2.36.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap