Currently attempting to debug with KDbg / gdb the source code for Towers of Hanoi from http://www.kernelthread.com/projects/hanoi//html/asm.html (great resource)
Since I wanted to review how the stack is used within this problem, I assembled it with NASM and used GCC to link it. However, I noticed that in KDbg, the current point of execution was not updating (i.e, I could not tell where I was within the file). Since KDbg relies on gdb, I ran the code within gdb to see if I experienced similar issues.
If I set a breakpoint on line #30 in the program (which is a line within the main function), I get the following:
(gdb) break 30
Breakpoint 2 at 0x804840b: file hanoi.asm, line 30.
(gdb) next
Single stepping until exit from function main,
which has no line number information.
I'm currently compiling the assembly with the following little script I've written (I should probably migrate to a make file, but this has been working up until now)
bschlinker#net1develop02:~/.scripts$ cat asmgcc
# /usr/bin/sh
nasm -f elf -g -F stabs $1.asm -l $1.lst
gcc -g $1.o -o $1
I just migrated from CentOS to Ubuntu, so I'm not sure if this is an OS environment issue I'm not familiar with, or another issue.
As always, thanks in advance for any assistance.
Try -F dwarf instead of -F stabs.
You can assemble with as -o tmp.o something.s && ld -s -o something tmp.o && rm tmp.o.
In gdb just display/8i *$eip (or rip if 64 bit), it will display 8 instructions after instruction pointer with every step. So you don't need debugging info at all ;-)
Related
So for awhile I have been using the Irvine library to kind of dip my toes into assembly (masm) language. Moving up in the world I want to get off the training wheels and let go of the Irvine library and jump into the pool with nasm on mac OSX. The problem here is I cannot even get terminal to open up the simple nasm hello world file.
The scene looks like this:
simple nasm hello world file written and saved to desktop
terminal is opened up and
nasm -f macho64 -o hello.o hello.asm (I have also tried .nasm and macho and macho32)
is inserted into the terminal.
A fatal error occurs which does not allow me to continue the learning process.
nasm: fatal: unable to open input file 'hello.asm'
Any help would be greatly appreciated because I have looked up a solution but cannot find any "helpful" advice. (Quotation marks because the advice is just not specifically helpful to my situation, or does not work to solve the problem.)
So the problem here was very simple and I hate myself a little for not realizing my mistake. The answer to this was very simple: to allow permissions with sudo.
`sudo nasm -f macho32 -o hello.o hello.asm`
You live and you learn I suppose.
Context:
go 1.2, ubuntu 12.10
Goal:
Reduce size of compiled binaries
Currently in my build process, I run "go install" to generate the binary.
The I read from somewhere that if I pass in -w it will shrink the binary.
I tried it by passing it into the -ldflags option & my binary lost 1MB in size.
Is this -w flag documented anywhere? What does it actually do?
I then discovered the strip -s <binary> command and ran that on top of -w and got
another weight loss of 750KB ! The resulting binary runs fine. Does stripping
cause problems in any situations ?
You will get the smallest binaries if you compile with -ldflags '-w -s'.
The -w turns off DWARF debugging information: you will not be able to use gdb on the binary to look at specific functions or set breakpoints or get stack traces, because all the metadata gdb needs will not be included. You will also not be able to use other tools that depend on the information, like pprof profiling.
The -s turns off generation of the Go symbol table: you will not be able to use go tool nm to list the symbols in the binary. strip -s is like passing -s to -ldflags but it doesn't strip quite as much. go tool nm might still work after strip -s. I am not completely sure.
None of these — not -ldflags -w, not -ldflags -s, not strip -s — should affect the execution of the actual program. They only affect whether you can debug or analyze the program with other tools.
You can get help from go tool link
$ go tool link
...
-s disable symbol table
-w disable DWARF generation
The go help build says that
-ldflags 'flag list'
arguments to pass on each 5l, 6l, or 8l linker invocation.
So, we can invoke go tool 6l to see all it's options. One of them is
-w disable DWARF generation
By the way, 5l stands for ARM ($GOARCH = arm), 6l stands for x86-64 ($GOARCH = amd64), and 8l is for x86 ($GOARCH = 386).
If you really want to view raw DWARF info you should use dwarfdump -a on OS X and objdump -wg on Linux. Warning! Output will be long, very long.
I'm afraid it might cause problems in programs compiled with Go 1.2's gc suite of tools—refer to this discussion.
The general idea is that while Go compiles down to machine code just like C, it's more higher-level than C. For instance, it has built-in detailed panic() stack traces which depend on debug info. The sizes of the gc-generated binaries could indeed have been smaller, and it might be addresseed while cooking Go 1.3, but really the size of a compiled program in most today's environments is not a big deal to be too concerned about.
I wrote a x86 assembly program for MBR section.
I compile it as follows:
nasm hellombr.asm -f bin -o hellombr.img
Then I run it in qemu:
qemu -fda hellombr.img -boot a
The question is how can I debug my program at source level?
You should let nasm create the debugging symbols in an ELF file and then dump this to a flat binary to be used in the MBR. You can then instruct GDB to read the necessary symbols from the ELF file.
The complete procedure would then become something like this:
$ nasm hellombr.asm -f elf -g -o hellombr.elf
$ objcopy -O binary hellombr.elf hellombr.img
$ qemu -s -S -fda hellombr.img -boot a
$ gdb
(gdb) symbol-file hellombr.elf
(gdb) target remote localhost:1234
For an explanation of the flags I pass to qemu see this answer.
Instead of using qemu, use bochs. It is completely compatible, albeit slower. It is also an emulator but if you make it from sources, using these flags and build it like this:
./configure --enable-debugger --enable-disasm --disable-docbook
make
make install
you can place breakpoints in your code, step through it, view GDT, IDT and everything you needed to know.
A really good (and simple) way is to use IDA with bochs, you find an excellent blog post on it here, along with some other hints/suggestions for bootloader development.
Is there any gcc option I can set that will give me the line number of the segmentation fault?
I know I can:
Debug line by line
Put printfs in the code to narrow down.
Edits:
bt / where on gdb give No stack.
Helpful suggestion
I don't know of a gcc option, but you should be able to run the application with gdb and then when it crashes, type where to take a look at the stack when it exited, which should get you close.
$ gdb blah
(gdb) run
(gdb) where
Edit for completeness:
You should also make sure to build the application with debug flags on using the -g gcc option to include line numbers in the executable.
Another option is to use the bt (backtrace) command.
Here's a complete shell/gdb session
$ gcc -ggdb myproj.c
$ gdb a.out
gdb> run --some-option=foo --other-option=bar
(gdb will say your program hit a segfault)
gdb> bt
(gdb prints a stack trace)
gdb> q
[are you sure, your program is still running]? y
$ emacs myproj.c # heh, I know what the error is now...
Happy hacking :-)
You can get gcc to print you a stacktrace when your program gets a SEGV signal, similar to how Java and other friendlier languages handle null pointer exceptions. See my answer here for more details:
how to generate a stacktace when my C++ app crashes ( using gcc compiler )
The nice thing about this is you can just leave it in your code; you don't need to run things through gdb to get the nice debug output.
If you compile with -g and follow the instructions there, you can use a command-line tool like addr2line to get file/line information from the output.
Run it under valgrind.
you also need to build with debug flags on -g
You can also open the core dump with gdb (you need -g though).
If all the preceding suggestions to compile with debugging (-g) and run under a debugger (gdb, run, bt) are not working for you, then:
Elementary: Maybe you're not running under the debugger, you're just trying to analyze the postmortem core dump. (If you start a debug session, but don't run the program, or if it exits, then when you ask for a backtrace, gdb will say "No stack" -- because there's no running program at all. Don't forget to type "run".) If it segfaulted, don't forget to add the third argument (core) when you run gdb, otherwise you start in the same state, not attached to any particular process or memory image.
Difficult: If your program is/was really running but your gdb is saying "No stack" perhaps your stack pointer is badly smashed. In which case, you may be a buffer overflow problem somewhere, severe enough to mash your runtime state entirely. GCC 4.1 supports the ProPolice "Stack Smashing Protector" that is enabled with -fstack-protector-all. It can be added to GCC 3.x with a patch.
There is no method for GCC to provide this information, you'll have to rely on an external program like GDB.
GDB can give you the line where a crash occurred with the "bt" (short for "backtrace") command after the program has seg faulted. This will give you not only the line of the crash, but the whole stack of the program (so you can see what called the function where the crash happened).
The No stack problem seems to happen when the program exit successfully.
For the record, I had this problem because I had forgotten a return in my code, which made my program exit with failure code.
So I wrote buggy code that occasionally crash ... and creates a stackdump file.
Using addr2line I can figure out how the program got to the crash point by decoding the addresses from the stackdump one by one. Is there an alternative tool that can ease the debug using stack dumps?
Is there a way to to load this information in Insight/Gdb?
You can instruct Cygwin to start your gdb debugger just in time when an fault occurs.
To achieve this, add error_start=action to the Cygwin environment variable:
export CYGWIN="$CYGWIN error_start=gdb -nw %1 %2"
Else you can have Cygwin generate a real core dump.
export CYGWIN="$CYGWIN error_start=dumper -d %1 %2"
Firstly, make sure you build with source debugging enabled (the using -g option):
gcc -g -o myfile myfile.c
Then Load the dump into gdb after the crash (or insight, or ddd)
gdb myfile core