main.lv
Dont think code it

2015-6-22 GDB helper functions

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                              GDB helper functions                            +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                    INDEX                                     +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1. Intro
2. Source
3. First run
4. Breakpoints
5. Registers
6. Helper commands
7. ToDo
8. Links

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                     1.Intro                                  +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


GDB is GNU debugger. It comes as standard tool in gcc toolchain and all distros 
have it as package. It work on all arch'es that gcc supports and it also can be 
used as remote debugger. To debug it uses Linux kernel debugging functionality 
of ptrace. For first moment its quite confusing tool too many command to type 
and it doesn't have GUI or TUI. 

What here will be added is command to show XMM registers, general purpose 
registers and eflags with one command. This command make gdb more fun tool
to use. 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                    2.Source                                 +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


You can find GDB source here http://ftp.gnu.org/gnu/gdb/

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                   3.First run                                +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


For first run we have example of program that just prints some string and
that's all. If you just run program with debugger and you haven't given commands
to debugger it will run program as expected if everything is OK with program. 

SOURCE: main1.c

#include 

{	
	printf("Works fine\n");
}
 

Firs run is 
	
	gdb ./main1

then in gdb command line type

	(gdb) run

And it will show 

	Starting program: main1
	Works fine
	[Inferior 1 (process XXX) exit normally]

String "Works fine" comes from printf's. And as everything was alright with
program its terminated "normally". Lets start to go deeper in debugging things.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                  4.Breakpoints                               +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Now lets use break points first breakpoint when to see whats happens in 
program is set at main/_start function of C program as its start point
of program. If program is written in assembler then there could be no
main function like in C but still there entry point to program. And 
possible why how to get address of entry point(main/_start) to program is
with readelf utility

	>readelf -h ./main1 | grep Entry

    Entry point address:               0x400410

Setting breakpoint to main function first way is just

	>gdb ./main1
	(gdb)break main
	Breakpoint 1 at 0x40050a
	(gdb)run
	Start program: ./main1
	Breakpoint 1, 0x040050a in main()

Now we called C main function and stopped at needed location.
Entry point is different in C it could be settuped directly with address or
	
	(gdb) break _start

breakpoint on address

	(gdb) break *0x400410

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                   5.Registers                                +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Moment when you need debugger is when something "broken" here is example
situation of broken code.

SOURCE: main2.c

int main()
{ 
	int i;

	i = i/0;
}

Run until it break and see what happened
	
	gdb ./main2
	(gdb) run
	Program received signal SIGFPE
	(gdb) display/i $pc
	=> 0x4004c3 :  idiv   %ecx


when number is divided on zero CPU usually generates exception and stops
program showing that something bad is happened. 


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                6.Helper commands                             +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


To improve your experience there could be written macroses that can improve
your experience with gdb. There is example of gdb macroses that could be useful
and if you want to use them you can put gdbalias file at same directory as 
debugged file and load from gdb with
	
	(gdb)source gdbalias

shr32        - show 32 bit general purpose registers
shr32a       - show 32 bit registers with 16, 8 bit registers and system registers
shr64        - show 64 bit general purpose registers
shr64a       - show 64 bit registers and 32/16/8 bit equivalents
shsse_float  - show xmm registers and its 4  32 bit float values
shsse_double - show xmm registers and its 2  64 bit double values
shsse_i8     - show xmm registers and its 16  8 bit integer values
shsse_i16    - show xmm registers and its 8  16 bit integer values
shsse_i32    - show xmm registers and its 4  32 bit integer values
shsse_i64    - show xmm registers and its 2  64 bit integer values
s            - one step in debugger
flags        - show eflags
showrchanges - on every step show changes from previous step
sc           - one step and show changed registers

All register could be printed with gdb command 

	printf

registers name that are used is $rax, $eax, $ax, $ah, $al and all others

shsee commands are showing xmm0 registers and what is inside depends
on you interpretation that why there is 8 registers

	$xmm0,$xmm1,$xmm2,$xmm3,$xmm4,$xmm5,$xmm6,$xmm7

and values depended on interpretation can be accessed as 

X - register index, Y - array index

	$xmmX.v4_float[0]
	$xmmX.v2_double[0]
	$xmmX.v16_int8[0]
	$xmmX.v8_int16[0]
	$xmmX.v4_int32[0]
	$xmmX.v2_int64[0]h

Changes on each step are made just by saving registers:

	set $oldrax = $rax

and when changes happens if/else:

	if ($rax != $oldrax)
		printf "RAX:0x016lX ", $rax
	end

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                     7.ToDo                                   +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Add more descriptions and more basic topics how to use gdb

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+                                     8.Links                                  +
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

[1] http://ftp.gnu.org/gnu/gdb/
[2] https://en.wikipedia.org/wiki/GNU_Debugger
[3] https://github.com/gdbinit/Gdbinit/blob/master/gdbinit
[4] https://sourceware.org/gdb/onlinedocs/gdb/Define.html
[5] https://github.com/FreeArtMan/gdbalias
[6] http://www.delorie.com/gnu/docs/gdb/gdb_28.html
[7] http://www.delorie.com/gnu/docs/gdb/gdb_29.html



Downloads

gdbalias14KiB