Linux Debugging using a Bootloader with Kernel Parameters
The grub menu.lst
provides for a convenient way to add a number of entries with extended kernel parameters to configure all sorts of advanced settings to enable you to quickly and conveniently boot into your existing system with varying levels of debugging output. It's very easy and useful to create several levels of debugging just by adding additional entries to your grub configuration. And if you ever have issues or problems down the road due to a power-failure or hardware failure, it can save you hours of trouble, and of course nothing can beat debugging output when it comes to learning about your system.
2013-04-11: My /proc/cmdline optimized for super duper speed, not debugging.root=UUID ro rootfstype=ext4 video=DVI-D-1:1920x1200 elevator=noop selinux=0 plymouth.enable=0 libahci.ignore_sss=1 raid=noautodetect ipv6.disable=1 cgroup_disable=memory
Useful Menu.lst Entries
If you are interested in debugging, then you deserve some grub entries for powerusers, here are a few that I like (just add to your menu.lst
).
title Shutdown the Computer halt title Reboot the Computer reboot title Command Line commandline title Install GRUB to hd0 MBR root (hd0,0) setup (hd0) title Matrix color green/black light-green/green title Scan for /boot/grub/menu.lst find --set-root --ignore-floppies /boot/grub/menu.lst configfile /boot/grub/menu.lst title Scan for /boot/menu.lst find --set-root --ignore-floppies /menu.lst configfile /boot/menu.lst # http://www.vortex.prodigynet.co.uk/x86test/ title Run x86test (CPU Info) kernel /boot/x86test_zImage.bin #wget http://www.vortex.prodigynet.co.uk/x86test/x86test_zImage.bin # http://www.memtest.org/ title Run memtest86+ (Memory Testing) kernel /boot/memtest86+-1.70.bin
Light Debug
A quick way to see more verbose messages on your console is to bootup your normal grub entry after appending verbose to the kernel line. This simple word added to your kernel line turns on more logging thanks to the /etc/rc.sysinit
file, which at the top of the file runs:
if /bin/grep -q " verbose" /proc/cmdline; then /bin/dmesg -n 8; fi
Very simple way to get a bit more messages and debug output in your logs.
title Arch Linux DEBUG Light kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootwait verbose initrd /kernel26.img
Medium Debug
This example menu.lst
entry turns on real logging that is set by the kernel and not in an init script. Adding the debug kernel parameter to your kernel line is recognized by a lot of linux internals and enables quite a bit of debugging compared to the default.
title Arch Linux DEBUG Medium kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootdelay=5 panic=10 debug initrd /kernel26.img
Heavy Debug
An even more impressive kernel parameter is the ignore_loglevel, which causes the system to ignore any loglevel and keeps the internal loglevel at the maximum debugging level, basically rendering dmesg unable to lower the debug level.
title Arch Linux DEBUG Heavy kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootdelay=5 panic=10 debug ignore_loglevel initrd /kernel26.img
Extreme Debug
If the "Heavy Debug" seemed like a lot of output, thats about 1/2 of the logging that occurs with this example. This does a couple things, it uses the earlyprintk parameter to setup your kernel for "early" "printing" of messages to your "vga" screen. The ,keep just lets it stay on the screen longer. This will let you see logs that normally are hidden due to the boot-up process. This also changes the log buffer length to 10MB, and also instructs that any fatal signals be printed with print_fatal_signals. The last one, sched_debug, you can look up in the very excellent kernel documentation on kernel parameters.
title Arch Linux DEBUG Extreme kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro debug ignore_loglevel log_buf_len=10M print_fatal_signals=1 LOGLEVEL=8 earlyprintk=vga,keep sched_debug initrd /kernel26.img
Insane Debug
The first few debugging examples showed some really nice kernel parameters to turn on really verbose debugging. This kind of debugging is absolutely critical if you want to max out your system or just learn more about what is going on behind the scenes. But there is a final trick that is my favorite, it's the ability to set both environment variables, and more importantly, module parameters at boot.
As an example, here is the boot line that I am using at the moment on an older Dell Desktop, just to illustrate module parameters and environment vars.
title Arch Linux X-256 kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootwait pause_on_oops=5 panic=60 i915.modeset=1 no_console_suspend ipv6.disable=1 TERM=xterm-256color quiet 5 initrd /kernel26.img
Since it's low on both memory and CPU, I disable ipv6. I also turn on kernel modesetting for the i915 video card, set my terminal to be xterm-256color, and boot straight into X. This lets me use a very optimized arch-linux configuration, amazing how fast thanks to using slim as the login manager, ratpoison as my window manager, and terminal with tmux as my login shell, all from boot, as the pstree shows (plus Synergy!).
init,1 |-slim,3096 | |-X,3098 -nolisten tcp vt07 -auth /var/run/slim.auth | `-ratpoison,3107,askapache | |-terminal,5341 -x sh -c exec /usr/bin/tmux -2 -l -u -q attach -d -t tmux-askapache | | |-bash,11165 | | |-tmux,5345 -2 -l -u -q attach -d -t tmux-askapache | | `-{terminal},5346 | `-xscreensaver,3113 -no-splash |-synergyc,6121,galileo -f --name galileo-fire --restart 10.66.66.2:26666 | `-tmux,5348,askapache -2 -l -u -q attach -d -t tmux-askapache |-bash,5351 | `-ssh,9969 lug@askapache.com `-bash,5868 `-vim,11149 -p sda1/grub/menu.lst /boot/grub/menu.lst
That kind of optimized system is only possible if you first can figure out your system, by debugging both the kernel as previously illustrated, debugging the init process, and most importantly, by debugging the modules enabled for your system's hardware/firmware/software. Debugging modules is challenging but worth the effort, and then you are able to do some truly insane debugging from grub like the following example, note that the actual grub entry is all on one line, but I split it into 4 lines so you could see it all. This basically turns on every module on this little Dell desktop to be at the absolute max debug level. There is so much logging when I boot this that the system grinds to a halt and is slower than a TI-89 calculator (See Improve Boot Performance).
title Arch Linux DEBUG INSANE kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootwait ignore_loglevel debug debug_locks_verbose=1 sched_debug initcall_debug mminit_loglevel=4 udev.log_priority=8 loglevel=8 earlyprintk=vga,keep log_buf_len=10M print_fatal_signals=1 apm.debug=Y i8042.debug=Y drm.debug=1 scsi_logging_level=1 usbserial.debug=Y option.debug=Y pl2303.debug=Y firewire_ohci.debug=1 hid.debug=1 pci_hotplug.debug=Y pci_hotplug.debug_acpi=Y shpchp.shpchp_debug=Y apic=debug show_lapic=all hpet=verbose lmb=debug pause_on_oops=5 panic=10 sysrq_always_enabled initrd /kernel26.img
A couple key items from that grub entry are sysrq_always_enabled which forces on the sysrq magic, which really is a lifesaver when debugging at this level as your machine will freeze/stop-responding sometimes and it's nice to use sysrq to kill all tasks, change the loglevel, unmount all filesystems, or do a hard reboot. Another key parameter is the initcall_debug, which debugs the init process in excruciating detail. Very useful at times. The last parametery I find very useful is the udev.log_priority=8 to turn on udev logging.
Break Into Init
For instance, If you add break=y to your kernel cmdline, init will pause early in the boot process (after loading modules) and launch an interactive sh shell which can be used for troubleshooting purposes. (Normal boot continues after logout.) This is very similar to the shell that shows up if your computer gets turned off before it is able to shutdown properly. But using this parameter lets you enter into this mode differently at will.
title Arch Linux Init Break kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro rootwait break=y initrd /kernel26.img
Debugging init
This awesome parameter udev.log_priority=8 does the same thing as editing the file /etc/udev/udev.conf
except it executes earlier, turning on debugging output for udev. If you want to know your hardware, that is the key parameter right there. Another trick is if you change the /etc/udev/udev.conf
to be verbose, then you can make your initrd image include that file to turn on verbose udeb debugging by adding it to your {{Filename|/etc/mkinitcpio.conf} like:
FILES="/etc/modprobe.d/modprobe.conf /etc/udev/udev.conf"
, which on arch is as easy as
# mkinitcpio -p kernel26
Debugging udev is key because the initrd performs a root change at the end of its run to usually launch a program like /sbin/init as part of a chroot, and unless the new file system has a valid /dev directory, udev must be initialized before invoking chroot in order to provide /dev/console
.
exec chroot . /sbin/initdev/console 2>&1
So basically, you aren't able to view the logs that are generated before /dev/console is initialized by udev or by a special initrd you compiled yourself. One method the kernel developers use to be able to still get the log messages generated before /dev/console is available is to provide an alternative console that you can enable or disable from grub.
Net Console
If you read through the kernel documentation regarding debugging, you will hear about Netconsole, which can be loaded from the kernel line in GRUB, compiled into your kernel, or loaded at runtime as a module. Having a netconsole entry in your menu.lst
is most excellent for debugging slower computers like old laptops or thin-clients. It's easy to use. Just setup a 2nd computer (running arch) to accept syslog requests on a remote port, very fast and quick to do on arch-linux, 1 line to syslog.conf. Then you could use a log-color-parser like ccze to view all syslog logs, or just tail your everything.log. Then on your laptop, boot up and select the netconsole entry from the grub menu, and you will start seeing as much logging as you want on your syslog system. This logging lets you view even earlier log output than is available with the earlyprintk=vga kernel parameter, as netconsole is used by kernel hackers and developers, so it's very powerful.
title Arch Linux DEBUG Netconsole kernel /vmlinuz26 root=/dev/disk/by-label/ROOT ro netconsole=514@10.0.0.2/12:34:56:78:9a:bc debug ignore_loglevel initrd /kernel26.img
Hijacking cmdline
If you do not have access to GRUB or the kernel boottime cmdline, like on a server or virtual machine, as long as you have root permissions you can still enable this kind of simplistic verbose logging using a neat hack. While you cannot modify the /proc/cmdline
even as root, you can place your own cmdline file on top of /proc/cmdline, so that accessing /proc/cmdline actually accesses your file.
For example if I cat /proc/cmdline, I have the following:
root=/dev/disk/by-label/ROOT ro console=tty1 logo.nologo quiet
So I use a simple sed command to replace quiet with verbose like:
sed '/root=/s/ quiet/ verbose/g' /proc/cmdline > /root/cmdline
Then I bind mount /root/cmdline so that it becomes /proc/cmdline, using the -n option to mount so that this mount won't be recorded in the systems mtab.
mount -n --bind -o ro /root/cmdline /proc/cmdline
Now if I cat /proc/cmdline, I have the following:
root=/dev/disk/by-label/ROOT ro console=tty1 logo.nologo verbose
This is part of the GRUB article on the Arch Linux wiki that I contributed. As of now, just a copy.
« HOWTO: Uninstall CPANEL over SSHGoogle SEO Boost with WordPress 404 Plugin »
Comments