world leader in high performance signal processing
Trace: » gdb_snippets

GDB Debug Snippets

Debugging with gdb can be augmented greatly via the user of gdb scripts. The GDB manual covers all of this in depth, so this document will contain a bunch of useful snippets.

To load a script at runtime, you can name it .gdbinit and place it in the directory you execute gdb. Another way is to use the -x option and specify the script to load automatically.

Note that some of these may make sense only when running with kgdb.

Dump Peripheral Registers

define info-uart
    # only show read-destructive registers if user requests them ...
    set $UART_DESTROY = ($argc > 1)

    set $UART_BASE = $arg0
    set $UART_RBR = $UART_BASE + 0x0000
    set $UART_DLL = $UART_BASE + 0x0000
    set $UART_IER = $UART_BASE + 0x0004
    set $UART_DLH = $UART_BASE + 0x0004
    set $UART_IIR = $UART_BASE + 0x0008
    set $UART_LCR = $UART_BASE + 0x000C
    set $UART_MCR = $UART_BASE + 0x0010
    set $UART_LSR = $UART_BASE + 0x0014
    set $UART_SCR = $UART_BASE + 0x001C
    set $UART_GCTL = $UART_BASE + 0x0024

    set $UART_LCR_VAL = *(unsigned short*)$UART_LCR

    printf "Showing UART Registers at 0x%X\n", $UART_BASE

    set *(unsigned short*)$UART_LCR = $UART_LCR_VAL & 0xF7
    printf " RBR: "
    x/1th $UART_RBR
    printf " IER: "
    x/1th $UART_IER

    set *(unsigned short*)$UART_LCR = $UART_LCR_VAL | 0x80
    printf " DLL: "
    x/1th $UART_DLL
    printf " DLH: "
    x/1th $UART_DLH

    set *(unsigned short*)$UART_LCR = $UART_LCR_VAL

    if $UART_DESTROY
        printf " IIR: "
        x/1th $UART_IIR
    else
        printf " IIR: <skipped destructive read>"
    end
    printf " LCR: "
    x/1th $UART_LCR
    printf " MCR: "
    x/1th $UART_MCR
    if $UART_DESTROY
        printf " LSR: "
        x/1th $UART_LSR
    else
        printf " LSR: <skipped destructive read>"
    end
    printf " SCR: "
    x/1th $UART_SCR
    printf " GCTL: "
    x/1th $UART_GCTL
end
define info-uart0
    set $UART0_BASE = 0xFFC00400
    info-uart $UART0_BASE ($argc > 0)
end
define info-uart1
    set $UART1_BASE = 0xFFC02000
    info-uart $UART1_BASE ($argc > 0)
end

Dump Kernel Log Buffer

The kernel stores all of its printk() output in a circular buffer, so displaying this buffer properly requires a bit more work than just writing it as a string from the start.

define dump-dmesg
    set $start = log_start - logged_chars
    set $end = log_end
    set $buf = log_buf
    set $mask = log_buf_len - 1
    while ($start != $end)
        set $c = $buf[$start & $mask]
        set $start = $start + 1
        printf "%c", $c
    end
    printf "\n"
end

Process Information

psname, ps and lsmod were orginally written by linsyssoft.com, and are released under the GPL. They do the same as their run time equivilents. List the process names/numbers, list the process table, and list the installed modules.

define psname
	if $arg0 == 0 
		set $athread =  init_tasks[0]
	else 
		set $athread = pidhash[(($arg0 >> 8) ^ $arg0) & 1023]
	end
	if $athread != 0 
		while $athread->pid != $arg0 && $athread != 0
			set $athread = $athread->hash_next
		end
		if $athread != 0 
			printf "%d %s\n", $arg0, (char*)$athread->comm
		end
	end
end
define ps
	set $initthread = init_tasks[0]
	set $athread = init_tasks[0]
	printf "%d %s\n", $athread->pid, (char*)($athread->comm)
	set $athread = $athread->next_task
	while $athread != ($initthread)
		if ($athread->pid) != (0)
			printf "%d %s\n", $athread->pid, (char*)$athread->comm
		end
		set $athread = $athread->next_task
	end
end
define lsmod
    set $mod = (struct module*)module_list
    # the last module is the kernel, ignore it
    while $mod != &kernel_module
    	printf "%p\t%s\n", (long)$mod, ($mod)->name
	set $mod = $mod->next
    end
end