Reputation: 247
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
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
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
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
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