I am wondering which debugging tool I can use for an assembly program and how to use it.
I have written a simple bootloader in assembly. However, it is not quite working properly as I wished, even though I think the logic is correct. So, I am trying to use a debugger so that I can step through the bootloader, checking the register status and etc.
I tried GDB on Ubuntu, compiling my .asm to .elf and .o (Do I need to do it? If yes, what is the next step?) Also, I read that there is an internal debugger in Bochs simulator, but I can't quite find any document how to use it. I also have Visual Studio 2010, windbg, but I don't know how to use it for .asm file debugging.
If you have done this before, it would be an easy answer. Any help would be really appreciated.
Sincerely
If you want to debug bootloader code, you obviously need to run it in the same environment that the code itself is going to run in. As I'm sure you already know, bootloader code is executed in real mode once the BIOS finishes doing the POST. The bootloader is then loaded into memory at 7c00h and a jump to that address is executed.
Obviously, this kind of environment cannot be reliably emulated once you've got your computer running and a "real" operating system already loaded, since by that time your CPU is in protected mode (or long mode, if it's AMD64). Your only option at this point is to use QEMU or Bochs in order to emulate a real PC inside your operating system. I've used Bochs to debug some bootloader code I've written in the past and it worked quite well. Check the manual pages for more detailed instructions.
Related
I am trying to remotely debug a linux kernel running on an arm cortex-a9 target using jtag probe and gdb.
I can connect to the kernel and halt it with gdb. I am able to set breakpoints in the kernel code and gdb confirms there placement as well but the problem is that once I start the execution and issue a continue command, the breakpoints are never hit and the kernel continues to run....
Please help me out in this regard.
Thanks.
As pointed in this thread, you should set the breakpoints as hardware breakpoints, namely - using the hbreak command. Only then the breakpoints will be hit.
For anyone reading this, the debugger will not break with software breakpoints by default, see the relevant doc:
"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."
at https://www.kernel.org/doc/html/v4.14/dev-tools/kgdb.html
Disable RWX and recompile, then software breakpoints should work (they started working normally here after this)
Is some cases, KASLR (Kernel Address Space Layout Randomization) can be the culprit.
Even though you setup hbreak, the actual code location can be different from the address seen from the .elf file when using KASLR, so either pass --append "nokaslr" to the kernel boot argument, or configure the kernel with RANDOMIZE_BASE=n. This applies for arm64 and x86_64. (maybe other architectures too).
I was wondering if there was any way that I could debug a floppy disk emulation in Linux.
The main thing I want to be able to do is to see the values of registers and custom defined bytes and words as the emulation runs.
Another thing I would like to be able to do is to run the emulation one step at a time, and see what line of code my emulation is currently on.
I am currently just running my floppy disk image under qemu-system-x86_64 and letting it run without any feedback besides the emulation.
If anyone can supply me with something along the lines of command line statements that accomplish this sort of thing, and what programs I could either move to or install alongside to help me out, it would be much appreciated.
I don't have enough idea of qemu because I haven't used it much. But from your requirement perspective, I think you should try bochs emulator. It's quite easy to use and comes with a built-in debugger. Only thing is, you need to compile it from source (if on Linux) making sure the --enable-debug and --enable-disasm switches are enabled (alongwith any other options you might want to enable). (On Windows however, the debugger comes as a pre-built (separate) executable in the installation, but that's sort of irrelevant in your case I guess.)
I'm just getting started learning FreeScale DSCs (MC56F800x series). I've done some work with AVRs using both AVR Studio on Windows and Eclipse and avr-gcc on Linux. CodeWarrior is just not as intuitive.
Right now I'm stuck trying to debug a simple program. I start the debugger using the built-in simulator, but it never reaches the first line of main(). Instead it seems to get stuck in some initialization code (MC56F8006_init.asm), specifically this line:
;; Loop until OCCS_STAT[LCK0] = 1
wait_for_lock:
brclr #OCCS_STAT_LCK0,x:>OCCS_STAT,wait_for_lock
I've let it run for quite a while and it never gets past this. It's obviously waiting for something, but what? You would think the simulator would just work... argh. Maybe there's some options I can change to make it pass this step?
I'm going to keep digging and will post an answer here if I find it first.
Updates:
Here's what I've found:
OCCS
On Chip Clock Synthesis
brclr
Branch if Bits Clear
The instruction loops until OCCS_STAT LCK0 is set. This register means the on-chip oscillator's PLL has locked (waits for clock stabilization).
I'm still not sure why the simulator spins forever on this line, and how I can solve this without resorting to hacking up the init code (which is part of the code library and not within my project).
I am not familiar with the part or the simulator, but it seems likely that the simulator is instruction-set-only and does not simulate the PLL hardware.
In most embedded development systems, the run-time startup code is provided as source and you could modify it (or rather make a local copy in your project and assemble and link that to override the default start-up). Alternately you could simply place a breakpoint in this loop, and advance the program-counter register to get it out of the loop. In many debuggers it is possible to attach a script to a breakpoint to do this automatically.
I have compiled my own Kernel module and now I would like to be able to load it
into the GNU Debugger GDB. I did this once, a year ago or so to have a look
at the memory layout. It worked fine then, but of course I was too silly to
write down the single steps I took to accomplish this... Can anyone enlighten
me or point me to a good tutorial?
Thank you so much
For kernels > 2.6.26 (i.e. after May 2008), the preferred way is probably to use "kgdb light" (not to be confused with its ancestor kgdb, available as a set of kernel patches).
"kgdb light" is now part of the kernel (in by default in current Ubuntu kernels, for instance), and it's capabilities are improving fast (Jason Wessel is working on it - possible google key).
Drawback: You need two machines, the one you're debugging and the development machine (host) where gdb runs. Currently, those two machines can only be linked through a serial link.
kgdb runs in the target machine where it handles the breakpoints, stepping, etc. and the remote debugging protocol use to talk with the development machine.
gdb runs in the development machine where it handles the user interface.
An USB-to-serial adapter works OK on the development machine, but currently, you need a real UART on the target machine - and that's not so frequent anymore on recent hardware.
The (terse) kgdb documentation is in the kernel sources, in
Documentation/DocBook
I suggest you google around for "kgdb light" for the complete story.
Again, don't confuse kgdb and kgdb light, they come together in google searches but are mostly different animals. In particular, info from linsyssoft.com relate to the "ancestor" kgdb, so try queries like:
kgdb module debugging -"linsyssoft.com" -site:linsyssoft.com
and discard articles prior to May 2008 / 2.6.26 kernel.
Finally, for module debugging, you need to manually load the module symbols in the dev machine for all the code and sections you are interested in. That's a bit too long to address here, but some clues there, there and there.
Bottom line is, kgdb is a very welcome improvement but don't expect this trip to be as easy as running gdb in user mode. Yet. :)
It has been a while since I was actively developing drivers for Linux, so maybe my answer is a bit out of date. I would say you cannot use GDB. If at all, only to debug post mortem on dump files. To debug you should rather use a kernel debugger. Build the kernel with a kernel debugger enabled (there is one out-of-the box debugger for 2.6, which was lacking at the time I was active). I used the kernel patches for KDB from Sun ftp://oss.sgi.com/www/projects/kdb/download/, which I was quite happy with. A user space tool won't be of much use unless new gdb communicate somehow with the internal kernel debugger (which anyway you would have to activate)
I hope this gives you at least some hints, while not being a detailled answer. Better than no answer at all. Regards.
I suspect what you did was
gdb /boot/vmlinux /proc/kcore
Of course you can't actually do any debugging, but it's certainly good enough to have a poke around the kernel.
I have big system that make my system crash hard. When I boot up, I don't even have
a coredump. If I log every line that
get executed until my system goes down. I will find that evil code.
Can I log every source code line in GDB to a file?
UPDATE:
ok, I found the bug. It was nasty. The application I started did not
take the system down. After learning about coredump inspection with mdb, and some gdb stepping I found out that the systemcall causing the dump, was not implemented. Updating the system to latest kernel will fix my problem. Thanks to all of you.
MY LESSON:
make sure you know what process causes the coredump. It's not always the one you started.
Sounds like a tricky little problem.
I often try to eliminate as many possible suspects as I can by commenting out large chunks of code, configuring the system to not run certain pieces (if it allows you to do that) etc. This amounts to doing an ad-hoc binary search on the problem, and is a surprisingly effective way of zooming in on offending code relatively quickly.
A potential problem with logging is that the log might not hit the disk before the system locks up - if you don't get a core dump, you might not get the log.
Speaking of core dumps, make sure you don't have a limit on your core dump size (man ulimit.)
You could try to obtain a list of all the functions in your code using objdump, process it a little bit and create a bunch of GDB trace statements on those functions - basically creating a GDB script automatically. If that turns out to be overkill, then a binary search on the code using tracepoints can also help you zoom in on the problem.
And don't panic. You're smarter than the bug - you'll find it.
You can not reasonably track every line of your source using GDB (too slow). Besides, a system crash is most likely a result of a system call, and libc is probably doing the system call on your behalf. Even if you find the line of the application that caused OS crash, you still don't really know anything.
You should start by clarifying which OS is crashing. For Linux, you can try the following approaches:
strace -fo trace.out /path/to/app
After reboot, trace.out will contain syscalls the application was doing just before the crash. If you are lucky, you'll see the last syscall-of-death, but I wouldn't count on it.
Alternatively, try to reproduce the crash on the user-mode Linux, or on kernel with KGDB compiled in.
These will tell you where the problem in the kernel is. Finding the matching system call in your application will likely be trivial.
Please clarify your problem: What part of the system is crashing?
Is it an application?
If so, which application? Is this an application which you have written yourself? Is this an application you have obtained from elsewhere? Can you obtain a clean interrupt if you use a debugger? Can you obtain a backtrace showing which functions are calling the section of code which crashes?
Is it a new hardware driver?
Is it based on an older driver? If so, what has changed? Is it based on a manufacturer's data sheet? Is that data sheet the latest and most correct?
Is it somewhere in the kernel? Which kernel?
What is the OS? I assume it is linux, seeing that you are using the GNU debugger. But of course, that is not necessarily so.
You say you have no coredump. Have you enabled coredumps on your machine? Most systems these days do not have coredumps enabled by default.
Regarding logging GDB output, you may have some success, but it depends where the problem is whether or not you will have the right output logged before the system crashes. There is plenty of delay in writing to disk. You may not catch it in time.
I'm not familiar with the gdb way of doing this, but with windbg the way to go is to have a debugger attached to the kernel and control the debugger remotely over a serial cable (or firewire) from a second debugger. I'm pretty sure gdb has similar capabilities, I could quickly find some hints here: http://www.digipedia.pl/man/gdb.4.html