Hexagon GDB Debugger介绍(25)
2.12.13 字符集
如果调试器和被调试程序使用不同的字符集来表示字符和字符串,调试器可以自动为你在字符集之间进行转换。调试器使用的字符集称为宿主字符集,而劣等程序使用的字符集称为目标字符集。
例如,如果你在 GNU/Linux 系统上运行调试器,该系统使用 ISO Latin 1 字符集,但你正在使用调试器的远程协议(参见第 3.3 节)来调试在 IBM 大型机上运行的程序,它使用EBCDIC 字符集,则宿主字符集为 Latin-1,目标字符集为 EBCDIC。 如果你向调试器提供命令 set target-charset EBCDIC-US,则调试器会在你打印字符或字符串值或在表达式中使用字符和字符串文字时在 EBCDIC 和拉丁文 1 之间进行转换
调试器无法自动识别劣等程序使用的字符集; 你必须使用 set target-charset 命令告诉它,如下所述。
以下是用于控制调试器字符集支持的命令:
set target-charset charset
将当前目标字符集设置为字符集。 我们在下面列出了调试器识别的字符集名称,但是如果你键入 set target-charset 后跟 ,调试器将列出它支持的目标字符集。
set host-charset charset
将当前主机字符集设置为字符集。
默认情况下,调试器使用适合它运行的系统的主机字符集; 你可以使用 set host-charset 命令覆盖该默认值。
调试器只能使用某些字符集作为其主机字符集。 我们在下面列出了调试器识别的字符集名称,并指出哪些可以是主机字符集,但是如果你键入 set target-charset 后跟 ,调试器将列出它支持的主机字符集。
set charset charset
将当前主机和目标字符集设置为字符集。 如上所述,如果你键入 set charset 后跟 ,调试器将列出可用于主机和目标的字符集的名称。
show charset
显示当前主机和目标字符集的名称。
show host-charset
显示当前主机字符集的名称。
show target-charset
显示当前目标字符集的名称。
调试器目前包括对以下字符集的支持:
ASCII
七位美国 ASCII。 调试器可以使用它作为它的主机字符集。
ISO-8859-1
ISO 拉丁语 1 字符集。 这使用法语、德语和西班牙语所需的重音字符扩展了 ASCII。 调试器可以使用它作为它的主机字符集。
EBCDIC-US
IBM1047
EBCDIC 字符集的变体,用于一些 IBM 的大型机操作系统。 (S/390 上的 GNU/Linux 使用 US ASCII。)调试器不能将这些用作其主机字符集。
注意
这些都是单字节字符集。 需要在调试器内部进行更多工作以支持多字节或可变宽度字符编码,例如 Unicode 的 UTF-8 和 UCS-2 编码。
下面是调试器字符集支持的示例。 假设在文件 charset-test.c 中放置了以下源代码:
#include <stdio.h>
char ascii_hello[]
= {72, 101, 108, 108, 111, 44, 32, 119,
111, 114, 108, 100, 33, 10, 0};
char ibm1047_hello[]
= {200, 133, 147, 147, 150, 107, 64, 166,
150, 153, 147, 132, 90, 37, 0};
main ()
{
printf ("Hello, world!\n");
}
在这个程序中,ascii_hello 和 ibm1047_hello 是包含字符串 Hello, world! 的数组。 后跟换行符,以 ASCII 和 IBM1047 字符集编码。
我们编译程序,并在其上调用调试器:
$ hexagon-gcc -g charset-test.c -o charset-test
$ hexagon-gdb -nw charset-test
GNU gdb 2001-12-19-cvs
Copyright 2001 Free Software Foundation, Inc.
...
(hexagon-gdb)
我们可以使用 show charset 命令查看调试器当前使用哪些字符集来解释和显示字符和字符串:
(hexagon-gdb) show charset
The current host and target character set is `ISO-8859-1'.
(hexagon-gdb)
为了打印本手册,让我们使用 ASCII 作为我们的初始字符集:
(hexagon-gdb) set charset ASCII
(hexagon-gdb) show charset
The current host and target character set is `ASCII'.
(hexagon-gdb)
让我们假设 ASCII 确实是我们主机系统的正确字符集; 换句话说,让我们假设如果调试器使用 ASCII 字符集打印字符,我们的终端将正确显示它们。 由于我们当前的目标字符集也是 ASCII,因此 ascii_hello 的内容打印清晰:
(hexagon-gdb) print ascii_hello
$1 = 0x401698 "Hello, world!\n"
(hexagon-gdb) print *(ascii_hello+0)
$2 = 72 'H'
(hexagon-gdb)
调试器使用你在表达式中使用的字符和字符串文字的目标字符集:
(hexagon-gdb) print '+'
$3 = 43 '+'
(hexagon-gdb)
ASCII 字符集使用数字 43 来编码 + 字符。
调试器依赖于用户告诉它目标程序使用哪个字符集。 如果我们在目标字符集仍然是 ASCII 时打印 ibm1047_hello,结果是垃圾:
(hexagon-gdb) print ibm1047_hello
$4 = 0x4016a8 "\310\205\223\223\226k@\246\226\231\223\204Z%"
(hexagon-gdb) print *(ibm1047_hello+0)
$5 = 200 '\310'
(hexagon-gdb)
如果我们调用 set target-charset 后跟 ,调试器会告诉我们它支持的字符集:
(hexagon-gdb) set target-charset
ASCII EBCDIC-US IBM1047 ISO-8859-1
(hexagon-gdb) set target-charset
我们可以选择 IBM1047 作为我们的目标字符集,并再次检查程序的字符串。 现在 ASCII 字符串是错误的,但调试器将 ibm1047_hello 的内容从目标字符集 IBM1047 转换为主机字符集 ASCII,并且它们显示正确:
(hexagon-gdb) set target-charset IBM1047
(hexagon-gdb) show charset
The current host character set is `ASCII'.
The current target character set is `IBM1047'.
(hexagon-gdb) print ascii_hello
$6 = 0x401698 "\110\145%%?\054\040\167?\162%\144\041\012"
(hexagon-gdb) print *(ascii_hello+0)
$7 = 72 '\110'
(hexagon-gdb) print ibm1047_hello
$8 = 0x4016a8 "Hello, world!\n"
(hexagon-gdb) print *(ibm1047_hello+0)
$9 = 200 'H'
(hexagon-gdb)
如上所述,调试器使用你在表达式中使用的字符和字符串文字的目标字符集:
(hexagon-gdb) print '+'
$10 = 78 '+'
(hexagon-gdb)
IBM1047 字符集使用数字 78 对 + 字符进行编码。