检查内存时gdb如何显示十六进制和ASCII?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了检查内存时gdb如何显示十六进制和ASCII?相关的知识,希望对你有一定的参考价值。

使用x / 100c时,输出同时显示ascii和十进制。

0x111111: 40 '(' 40 '('

gdb如何同时显示ascii和hex?

like

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

此格式更好:

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

答案

您可以使用宏进行此操作。遍历字符,然后调用适当的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 "'
"
        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'
另一答案

很遗憾,没有内置方法。我认为这将是对gdb的不错补充。

同时,您可以通过在Python中编写新的转储命令来进行滚动。我认为这不会很困难。

另一答案
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 "'
"
        set $addr = $addr + 8
    end
end

上面的宏注意不可打印的ASCII字符。 Mark Plotnick给出的xac宏代码仅修改了1行。由于我不需要声誉,因此无法将其作为评论提及,因此发布为另一个答案。

以上是关于检查内存时gdb如何显示十六进制和ASCII?的主要内容,如果未能解决你的问题,请参考以下文章

如何 gdb 如何打印一个地址中的内容

x/nfu-用gdb查看内存

gdb里面怎么用16进制打印一块内存数据

解析ASCII十六进制转储以正确转换为二进制

检查 gdb 中的 C/C++ 堆内存统计信息

GDB 问题 - 我如何逐行查看反汇编代码?