简体   繁体   中英

How to set source encoding for 'list' command in GDB?

I have a project, Geki 2, which is written in C and uses a library called Kacchan X Library (libKXL for short) for graphics and sound. This library uses X11 API directly. When debugging Geki 2 under GDB in VirtualBox, GDB gives the following error when it tries to show part of the source code (KXLvisual.c) of the KXL library that Geki 2 uses:

Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xa1 in position 424: invalid start byte.

And when I list functions in KXLimage.c, I get this slightly different error:

Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xa4 in position 172: invalid start byte

Both the geki2 and KXL library have comments in Japanese and the encoding seems to be "euc-jp". The source code comments display fine in Vim after running :e ++enc=euc-jp and also looks fine on GitHub. The list command in GDB shows Unicode replacement characters and boxes instead of Japanese. The comment on line 76 of KXLvisual.c shows up as GC���� but it's supposed to be GC作成and the comment on line 79 shows up as ���᡼���˥��ԡ� but it should beイメージにコピー

How do I set the source encoding used by the list command in GDB to euc-jp?

I'm using bash shell in Konsole in a openSUSE 15.4 VirtualBox VM on a Windows 10 host. I would use WSL to debug geki2 except 1. WSL bug #547 makes it impossible to debug programs with just GDB on WSL1. I can run Valgrind with VGDB server and connect to Valgrind with GDB but this will run the program much slower, 2. euc-jp is a Unix-only encoding according to mbyte help file in Vim. 3. conhost.exe (the terminal for WSL) doesn't seem to support Unicode.

What I've tried: set target-wide-charset euc-jp in GDB but it just says 'Undefined item: "euc-jp".'

GDB output:

/mnt/d/src/geki2> gdb src/geki2
GNU gdb (GDB; SUSE Linux Enterprise 15) 11.1
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from src/geki2...
(gdb) set dir /mnt/d/src/geki2/src /mnt/d/src/libKXL/src
(gdb) r
Starting program: /mnt/d/src/geki2/src/geki2
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-150300.31.2.x86_64
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
url   : http://www2.mwnet.or.jp/~fc3srx7
email : fc3srx7@mwnet.or.jp

"geki2 --help" for command line parameters
[Detaching after fork from child process 30260]
^C
Program received signal SIGINT, Interrupt.
0x00007ffff7596d43 in writev () from /lib64/libc.so.6
Missing separate debuginfos, use: zypper install libFLAC8-debuginfo-1.3.2-3.9.1.x86_64 libX11-6-debuginfo-1.6.5-3.21.1.x86_64 libXau6-debuginfo-1.0.8-1.26.x86_64 libXcursor1-debuginfo-1.1.15-1.18.x86_64 libXfixes3-debuginfo-6.0.0-150400.1.4.x86_64 libcap2-debuginfo-2.63-150400.1.7.x86_64 libdbus-1-3-debuginfo-1.12.2-150400.16.52.x86_64 libgcrypt20-debuginfo-1.9.4-150400.4.6.x86_64 liblz4-1-debuginfo-1.9.3-150400.1.7.x86_64 liblzma5-debuginfo-5.2.3-150000.4.7.1.x86_64 libpulse0-debuginfo-15.0-150400.2.10.x86_64 libsndfile1-debuginfo-1.0.28-5.15.1.x86_64 libsystemd0-debuginfo-249.11-150400.6.8.x86_64 libvorbis0-debuginfo-1.3.6-4.3.1.x86_64 libvorbisenc2-debuginfo-1.3.6-4.3.1.x86_64 libxcb1-debuginfo-1.13-3.7.1.x86_64 libzstd1-debuginfo-1.5.0-150400.1.71.x86_64
(gdb) up
#1  0x00007ffff7069681 in ?? () from /usr/lib64/libxcb.so.1
(gdb)
#2  0x00007ffff7069a75 in ?? () from /usr/lib64/libxcb.so.1
(gdb)
#3  0x00007ffff7069afd in xcb_writev () from /usr/lib64/libxcb.so.1
(gdb)
#4  0x00007ffff78c50b6 in _XSend () from /usr/lib64/libX11.so.6
(gdb)
#5  0x00007ffff78c560c in _XReply () from /usr/lib64/libX11.so.6
(gdb)
#6  0x00007ffff78c109d in XSync () from /usr/lib64/libX11.so.6
(gdb)
#7  0x00007ffff7bc381c in KXL_Up_Date (src_l=<optimized out>, src_t=<optimized out>, src_w=<optimized out>, src_h=<optimized out>) at KXLvisual.c:44
Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xa1 in position 424: invalid start byte
44        XSync(KXL_Root->Display, False);
(gdb) l 76
71      KXL_Image *KXL_Copy_Image(KXL_Image *src, Uint16 src_l, Uint16 src_t, Uint16 src_w, Uint16 src_h)
72      {
73        GC gc8, gc1;
74        KXL_Image *dest;
75
76        // GC����
77        KXL_SetGC(src->Buffer, &gc8);
78        KXL_SetGC(src->Mask, &gc1);
79        // ���᡼���˥��ԡ�
80        dest         = (KXL_Image *)KXL_Malloc(sizeof(KXL_Image));
(gdb)

xxd output for KXLvisual.c (the offending byte is on the line starting with 000001a0)

00000000: 2369 6e63 6c75 6465 203c 7374 646c 6962  #include <stdlib
00000010: 2e68 3e20 2f2f 2066 6f72 2065 7869 740a  .h> // for exit.
00000020: 2369 6e63 6c75 6465 203c 7374 7269 6e67  #include <string
00000030: 2e68 3e20 2f2f 2066 6f72 2073 7472 6c65  .h> // for strle
00000040: 6e0a 2369 6e63 6c75 6465 203c 7374 6469  n.#include <stdi
00000050: 6f2e 683e 0a23 696e 636c 7564 6520 224b  o.h>.#include "K
00000060: 584c 2e68 220a 0a2f 2f3d 3d3d 3d3d 3d3d  XL.h"..//=======
00000070: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000080: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000090: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
000000a0: 3d3d 3d3d 3d3d 3d3d 3d0a 2f2f 2049 6e74  =========.// Int
000000b0: 6572 6e61 6c20 7661 7269 6162 6c65 7320  ernal variables 
000000c0: 616e 6420 6675 6e63 7469 6f6e 730a 2f2f  and functions.//
000000d0: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
000000e0: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
000000f0: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000100: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000110: 0a4b 584c 5f57 696e 646f 7720 2a4b 584c  .KXL_Window *KXL
00000120: 5f52 6f6f 743b 0a63 6861 7220 4b58 4c5f  _Root;.char KXL_
00000130: 444e 616d 655b 3130 3234 5d20 3d20 2222  DName[1024] = ""
00000140: 3b0a 0a2f 2f3d 3d3d 3d3d 3d3d 3d3d 3d3d  ;..//===========
00000150: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000160: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000170: 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d 3d3d  ================
00000180: 3d3d 3d0a 2f2f 2020 5365 7420 4743 2066  ===.//  Set GC f
00000190: 726f 6d20 7069 786d 6170 0a2f 2f20 2061  rom pixmap.//  a
000001a0: 7267 756d 656e 7473 a1a7 5069 786d 6170  rguments..Pixmap
000001b0: 0a2f 2f20 2020 2020 2020 2020 2020 a1a7  .//           ..
000001c0: 506f 696e 7465 7220 6f66 2047 430a 2f2f  Pointer of GC.//

The code that GDB chokes on (lines 1-106 from KXLvisual.c in libKXL):

#include <stdlib.h> // for exit
#include <string.h> // for strlen
#include <stdio.h>
#include "KXL.h"

//================================================================
// Internal variables and functions
//================================================================
KXL_Window *KXL_Root;
char KXL_DName[1024] = "";

//==============================================================
//  Set GC from pixmap
//  arguments:Pixmap
//           :Pointer of GC
//==============================================================
void KXL_SetGC(Pixmap p, GC *gc)
{
  *gc = XCreateGC(KXL_Root->Display, p,  0, 0);
  XSetGraphicsExposures(KXL_Root->Display, *gc, False);
}

//==============================================================
//  Update to window
//  arguments : Frame left
//            : Frame top
//            : Frame width
//            : Frame height
//==============================================================
void KXL_Up_Date(Uint16 src_l, Uint16 src_t, Uint16 src_w, Uint16 src_h)
{
  XCopyArea(KXL_Root->Display,
            // from frame
            KXL_Root->Frame->Buffer,
            // to window
            KXL_Root->Win,
            // gc
            KXL_Root->Frame->Gc,
            // from frame rectangle
            src_l, src_t, src_w, src_h,
            // to window position
            0, 0);
  //XFlush(KXL_Root->Display);
  XSync(KXL_Root->Display, False);
}

//==============================================================
//  Clear to frame
//  arguments : Frame left
//            : Frame top
//            : Frame width
//            : Frame height
//==============================================================
void KXL_Clear_Frame(Uint16 src_l, Uint16 src_t, Uint16 src_w, Uint16 src_h)
{
  XFillRectangle(KXL_Root->Display,
                 KXL_Root->Frame->Buffer,
                 KXL_Root->Frame->Gc,
                 src_l, src_t, src_w, src_h);
}

//==============================================================
//  Copy from source image to new image
//  arguments    : Pointer of source image
//               : Source image left
//               : Source image top
//               : Source image width
//               : Source image height
//  Return value : Pointer of new image
//==============================================================
KXL_Image *KXL_Copy_Image(KXL_Image *src, Uint16 src_l, Uint16 src_t, Uint16 src_w, Uint16 src_h)
{
  GC gc8, gc1;
  KXL_Image *dest;

  // GC作成
  KXL_SetGC(src->Buffer, &gc8);
  KXL_SetGC(src->Mask, &gc1);
  // イメージにコピー
  dest         = (KXL_Image *)KXL_Malloc(sizeof(KXL_Image));
  dest->Width  = src_w;
  dest->Height = src_h;
  dest->Buffer = XCreatePixmap(KXL_Root->Display, KXL_Root->Win,
                               src_w, src_h, KXL_Root->Depth);
  XCopyArea(KXL_Root->Display,
            src->Buffer,
            dest->Buffer,
            gc8,
            src_l, src_t, src_w, src_h,
            0, 0);
  dest->Mask = XCreatePixmap(KXL_Root->Display, KXL_Root->Win,
                             src_w, src_h, 1);
  XCopyArea(KXL_Root->Display,
            src->Mask,
            dest->Mask,
            gc1,
            src_l, src_t, src_w, src_h,
            0, 0);
  // クリップマスク作成
  dest->MaskGC = XCreateGC(KXL_Root->Display, KXL_Root->Frame->Buffer, 0, 0);
  XSetClipMask(KXL_Root->Display, dest->MaskGC, dest->Mask);
  // ローカル変数解放
  XFreeGC(KXL_Root->Display, gc8);
  XFreeGC(KXL_Root->Display, gc1);
  return dest;
}

I solved it. Turns out Konsole was using the wrong encoding; it was set to UTF-8 which caused the EUC-JP comments to show up as mostly U+FFFD replacement character. Setting the encoding in Konsole doesn't get rid of the GDB error but at least the comments display correctly now.

In Konsole,

  1. Click on "View"
  2. Set Encoding
  3. Japanese
  4. EUC-JP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM