Getting Linux kernel debug information after a kernel crash - c

Is there a way to get kernel previous debug information after kernel crash occurs.
I am trying to develop a kernel module which basically captures IP packets in the IP layer inside the kernel network stack and after some modification I have to send the same packet back to the NIC for transmission.
During all these processes I'm writing debug information with the help of printk(). But if any thing goes wrong and a kernel failure occurs, we have to restart the system. Is there a way to get my previous debug information, because after rebooting the debug information is not present as I try to get it by dmesg command?

Actually, the /var/log/dmesg file contains the current boot print message log. The /var/log/kern.log file contains your previous boot kernel print message log in Ubuntu. In other Linux flavours it will contain in the /var/log/messages file in Fedora, etc..

Kernel log messages can be viewed in /var/log/dmesg files even after restart of the system.
There will be so many files with dmesg.X, and those files are previous kernel logs. dmesg is the latest file.
See difference between dmesg and /var/log/kern.log

You could try to interact with your hung system by entering magic SysRq key sequences via your keyboard or a serial console.

Recent versions of Linux support crash dumps. When successful, these will include a full dump of memory, including kernel log messages and stack traces.

Actually, the crash information (dmesg) is present in the location /var/crash/.
Here we have the folders for every system crash. Folder names like 127.0.0.1-date-time. vmcore-dmesg.txt are present inside the folders. From these file, we have get the dmesg which are executed before the crash.

GNOME Logs is a very useful software for that. You can limit the log messages to the last session and easily read what the last messages before the crash were.

Related

Why does Jetson TK1 hang at "Starting kernel ..."

With freshly flashed L4T 21.8, the serial console stops with output like:
## Flattened Device Tree blob at 82000000
Booting using the fdt blob at 0x82000000
Using Device Tree in place at 82000000, end 83014f2d
Starting kernel ...
How do I get serial output from the kernel?
When things stop after "Starting kernel...", across boards, there are usually two causes:
serial console isn't enabled right
kernel didn't have enough space to unpack itself and start printing to serial console.
The first thing to enable is serial console. Make sure the kernel command line for TK1 includes:
console=ttyS0,115200n8 earlycon=uart8250,mmio32,0x70006300 earlyprintk
Two things are going on there: One is enabling normal serial console once boot gets far enough. The other is enabling earlycon before the proper 8250 driver is initialized, so you can see early boot failures too. This serial setup should get you output on the DB9 connector J1A2 (UART4) just like u-boot uses.
If you still don't have serial output with that, likely the issue is the kernel trashing the dtb while unpacking -- the default 16Mb between 0x81000000 kernel and 0x82000000 fdt is not enough for many kernels. You need to move the fdt address up to make space. Press the reset button, and interrupt the boot by pressing a key when prompted, then enter this in your u-boot command line:
set fdt_addr_r 0x83000000
saveenv
run bootcmd
This gets you 32MB of space for the kernel image for this boot, and thanks to saveenv also any following ones.

Kernel User I/O application development

I've read up on the following links about User I/O:
http://www.hep.by/gnu/kernel/uio-howto/
and followed http://nairobi-embedded.org/uio_example.html.
I'm using the ivshmem device to map memory from the host to the guest (in QEmu). The client driver that I'm using is kernel_module/uio/uio_ivshmem.c from https://www.gitorious.org/nahanni/guest-code.
I've had success sharing the memory between several guests, and I can also issue interrupts from the host to the guest, using the ivshmem-server from the git repository above.
But I cant figure out how I can "interrupt" from the guest to notice that writing to the memory is completed. I.e. signal to the other guest that it should read what the first guest has written.
What am I doing wrong? Is there any way to send interrupts using UIO or can I only receive? How else am I supposed to notice that I'm done writing/reading?
Ok, I've now figured out why I cant send interrupts.
I did try using the test applications, but, as you can read in this (http://lists.gnu.org/archive/html/qemu-devel/2014-08/msg05388.html) post, a patch in the kernel broke uio_ivshmem.c.
This patch made ivshmem unable to map BAR0, which is used to send interrupts. BAR2 is still fine and can be used to share data, though interrupts wont work.

Locking the frame buffer device

I am developing an application for linux based embedded system which directly writes on the framebuffer device of the Linux kernel.The writing works perfectly. But the problem happens when some other event occurs with a demand of display(Like plugging a flash drive or a kernel message). Every time when it happens, the screen gets interrupted and the unwanted things appear on the screen erasing the previous graphics from the overlapped portion(other things remain unchanged).
How can I get rid of this problem?
Add console=0 to the kernel command line. It disables both the kernel outputting anything to the console, and the console login. (For development purposes, I recommend having a separate boot option, so you can boot to a console.)
Alternatively, have your application create a new virtual terminal for the framebuffer, like X does. This avoids the kernel (kernel console, really) scribbling text all over your framebuffer.

How do I get Linux hardware and system info via a C library?

I'm trying to implement a system which sends via Bluetooth sockets, information about the current system (in fact, a Linux server). This back-end code is in C. I'd like to know if there's an available library to get info like cpu temperature, disk usage and process running, just to name a few inside C code. If it's not possible, what kind of alternatives do you suggest to me ?
To find disk usages - see lstat(), pick st_size to get the size of file and get the disk usages. No of running processes could be found by reading /proc, all the running processes has pidno under /proc. And, currently, I'm unaware of how to get cpu temperature. But, you can get cpufreq related info from /sys/devices/system/cpu/cpufreq.

linux usb connect/disconnect event

Hello I am working on an embedded linux device with a usb port that uses the g_ether driver for usb networking.
When the usb plug is connected the dmesg output is:
g_ether gadget: full speed config #2: RNDIS
When the usb cable is unplugged no message is written to dmesg.
Using C how can I listen for the connect/disconnect events?
The embedded linux OS does not have any extras. There is no dbus daemon or hotplug helper script. I am not even sure if these would of been helpful.
If you want everything in your single process, you'll have to use libudev to either get events from udevd or directly from the kernel.
Seeing that it might be a problem to use libudev in your application (lack of documentation?), an alternative is to use the udevadm program, which can:
report device events after being processed by udevd (udevadm monitor --udev --property),
report devive events directly from the kernel (udevadm monitor --kernel --property), and
dump udevd's database of current devices (but not the kernel's!) (udevadm info --query all --export-db)
udevadm is part of the udev package, but shouldn't need udevd if you only use it to report kernel events. You can use it by having your process spawn it and parse its standard output (but you'll have to launch it via stdbuf -o L ).
Either way, it'll probably be a lot of work. I've already implemented a lot of this in my NCD programming language, including monitoring of USB devices. You might want to take a look at NCD; it's useful for a lot of configuration tasks, and handles hotplugging well. For example, this NCD program will print USB device events to standard output:
process main {
sys.watch_usb() watcher;
println(watcher.event_type, " ", watcher.devname, " ", watcher.vendor_id, ":", watcher.model_id);
watcher->nextevent();
}
This will make NCD print something like that (with an initial added event for any USB device that was already plugged in):
added /dev/bus/usb/002/045 0409:0059
added /dev/bus/usb/002/046 046d:c313
added /dev/bus/usb/002/047 046d:c03e
added /dev/bus/usb/002/048 0557:2008
removed /dev/bus/usb/002/048 0557:2008
You can also use NCD just for this, and parse this standard output - which is much easier to work with than messing with udevadm directly.
Note that NCD itself uses udevadm, and it does require udevd to be running; but why is that a problem anyway? (with some work this dependency could be removed)
You can use libudev or parse udevadm output as #Ambroz Bizjak suggested. Although, I advise against adding an additional process (stdbuf) and language (NCD), just to parse udevadm's output.
A step between plain libudev and parsing output is modifying the udevadm sources. This solution reduces the needed resources and skips the parsing process altogether. When you look at the udev package, you will find the sources for udevd and udevadm in the udev directory.
There, you have the main routine in udevadm.c and the source for udevadm monitor in udevadm-monitor.c. Every event received will be printed through print_device(). This is where you insert your code.
If you're tight on memory, you can strip off unneeded code for control, info, settle, test-builtin, test and trigger. On my system (Ubuntu 12.04), this reduces the size of udevadm by about 75%.
Unfortunately, there is no udev event produced on connect/disconnect on gadget side, so it is almost impossible to monitor these events.
You could monitor kernel messages (dmesg). It seems to be a stupid idea. Or watch some files in sysfs. Maybe the better way is kernel patching.
update: I do not understand why this answer have got many negative votes.
Maybe some people mix USB host part (which produces UDEV events on device plug/unplug) and USB device/gadget part (which doesn't produce such events)
If your linux host works as a gadget (USB device which is connected to some USB host) there is no good way to catch plug/unplug events.
Proof: message by Greg Kroah-Hartman
another copy if previous link is down

Resources