6

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...'

4 Answers 4

13

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'
Sign up to request clarification or add additional context in comments.

4 Comments

How do you load this macro into gdb?
@0x64 Put it into a file and in gdb type source /path/to/file.
@0x64 You can also put it into ~/.gdbinit. This file is sourced into gdb by default at startup. If the file does not exist then you can create it.
@markplotnick note to self: add another answer: with recent GDB, use pipe command to send dump binary memory to xxd.
3

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.

Comments

2
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.

Comments

1
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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.