jinleileiking
jinleileiking

Reputation: 247

How can gdb show both hex and ascii when examing memory?

When using x/100c, the output shows the both ascii and decimal.

0x111111: 40 '(' 40 '('

How can gdb show the ascii and hex at the same time ?

like

0x111111: 0x28 'C' 0x28 'C'

This format is better:

0x111111: 0x28 0x28 ... 'CC...'

Upvotes: 6

Views: 10980

Answers (4)

Drakorcarnis
Drakorcarnis

Reputation: 21

define xac
    dont-repeat
    if $argc == 3
        set $width = $arg2
    else
        set $width = 8
    end
    set $addr = (char *)($arg0)
    set $endaddr = $addr + $arg1
    while $addr < $endaddr
        printf "%p: ", $addr
        set $lineendaddr = $addr + $width
        if $lineendaddr > $endaddr
            set $lineendaddr = $endaddr
        end
        set $a = $addr
        while $a < $lineendaddr
            printf "0x%02x ", *(unsigned char *)$a
            set $a++
        end
        while $a < $addr + $width
            printf "     "
            set $a++
        end
        printf "'"
        set $a = $addr
        while $a < $lineendaddr
            printf "%c", *(char *)$a < 32 || *(char *)$a > 126 ? '.' : *(char *)$a
            set $a++
        end
        printf "'\n"
        set $addr = $addr + $width
    end
end

document xac
    usage: xac address count [width=8]
end

The above macro allows an optionnal width defaulted to 8. Morover, it ensures the ASCII representation stays on his own block. Just few lines modified in the code of xac macro given by the sudhakar. As I am not having needed reputation, could not mention it as a comment, hence posting as another answer.

Upvotes: 2

the sudhakar
the sudhakar

Reputation: 49

define xac2
    dont-repeat
    set $addr = (char *)($arg0)
    set $endaddr = $addr + $arg1
    while $addr < $endaddr
        printf "%p: ", $addr
        set $lineendaddr = $addr + 8
        if $lineendaddr > $endaddr
            set $lineendaddr = $endaddr
        end
        set $a = $addr
        while $a < $lineendaddr
            printf "0x%02x ", *(unsigned char *)$a
            set $a++
        end
        printf "'"
        set $a = $addr
        while $a < $lineendaddr
            printf "%c", *(char *)$a < 32 || *(char *)$a > 126 ? '.' : *(char *)$a
            set $a++
        end
        printf "'\n"
        set $addr = $addr + 8
    end
end

The above macro takes care non printable ASCII characters. Just 1 line modified in the code of xac macro given by Mark Plotnick. As I am not having needed reputation, could not mention it as a comment, hence posting as another answer.

Upvotes: 1

Mark Plotnick
Mark Plotnick

Reputation: 10271

You can do this with a macro. Iterate through the characters, and call appropriate printfs.

define xac
    dont-repeat
    set $addr = (char *)($arg0)
    set $endaddr = $addr + $arg1
    while $addr < $endaddr
        printf "%p: ", $addr
        set $lineendaddr = $addr + 8
        if $lineendaddr > $endaddr
            set $lineendaddr = $endaddr
        end
        set $a = $addr
        while $a < $lineendaddr
            printf "0x%02x ", *(unsigned char *)$a
            set $a++
        end
        printf "'"
        set $a = $addr
        while $a < $lineendaddr
            printf "%c", *(char *)$a
            set $a++
        end
        printf "'\n"
        set $addr = $addr + 8
    end
end

document xac
usage: xac address count
end


$ gdb co2
(gdb) list
1       #include <stdlib.h>
2       #include <stdio.h>
3
4       main()
5       {
6               char cmd[50];
7
8               sprintf(cmd, "cat /proc/%d/maps", getpid());
9               system(cmd);
10      }
(gdb) break 9
Breakpoint 1 at 0x400666: file co2.c, line 9.
(gdb) run
Breakpoint 1, main () at co2.c:9
9               system(cmd);
(gdb) xac cmd 20
0x7fffffffe110: 0x63 0x61 0x74 0x20 0x2f 0x70 0x72 0x6f 'cat /pro'
0x7fffffffe118: 0x63 0x2f 0x32 0x30 0x37 0x37 0x38 0x2f 'c/20778/'
0x7fffffffe120: 0x6d 0x61 0x70 0x73 'maps'

Upvotes: 13

Tom Tromey
Tom Tromey

Reputation: 22589

Unfortunately there is no built-in way. I think that would be a nice addition to gdb.

Meanwhile, you can roll your own by writing a new dumping command in Python. I think this would not be very hard.

Upvotes: 3

Related Questions