2009-11-12 215 views
4

作爲使用MS Visual Studio 作爲工作平臺的C++ Developer,我已經工作了幾年。由於我私下更喜歡使用linux,所以我最近也採用了 的機會將我的工作環境轉移到linux。 由於我幾年來一直在優化我的Windows環境, 當然,結果發現有幾件事情沒有按預期工作或沒有按預期工作。 因此,我有一些問題,我不能與有用的答案來。如何在linux上調試時顯示Unicode字符串?

讓我們開始下面的問題,稍後可能會出現不同的問題。 這個問題是我已經偶然發現了幾次, 每當我被迫在非Windows平臺上調試特定於平臺的錯誤。

簡單地說:如何在Linux上調試時顯示Unicode(UCS2編碼)字符串?

現在我已經計算了一些更多細節。我們的庫interally使用基於Unicode String類,它編碼每個字符的16位Unicode值(但我們不這樣做 支持多字的編碼,因此,我們基本上只能使用UCS2可編碼子UTF16的 ,但是這包括幾乎所有使用無論如何腳本)。 這已經引起了一個問題,因爲大多數平臺(即linux/unix)認爲 wchar_t類型由4個字節組成,而在Windows上它只有2個字節,因此我不能簡單地將內部字符串緩衝區轉換爲(wchar_t *),所以我不確定, 如果這真的會幫助任何調試器。

對於gdb我已經想通了,我可以從調試的代碼調用函數到 打印調試消息。因此,我在我們的lib中插入了一個特殊函數, 可以任意轉換字符串數據並將其寫入新的緩衝區。 目前,我將我們的內部緩衝區轉碼爲utf8,因爲我認爲 最有可能工作。

但到目前爲止,這只是部分地解決了這個問題:如果字符串是拉丁語, 話,我現在得到一個可讀的輸出(而一個不能直接打印拉丁 數據如果是16位編碼),但我也有處理其他腳本 (fe CJK(又名Hansi/Kanji),西里爾文,希臘語...)和處理我的意思是 我必須使用這樣的腳本專門調試數據,因爲使用的腳本直接影響控制流程 。 當然,在這些情況下,我只能看到與構成utf8字符的多個 字節對應的ISO字符,這使得調試CJK數據更加神祕,然後正確顯示字符串。

通常gdb允許設置多個主機和目標編碼,因此它應該是 是可能的,以將正確編碼的utf8數據流發送到控制檯。

但我當然更喜歡使用IDE進行調試。目前我正在嘗試 與eclipse和CDT交朋友,但爲了調試,我也測試了kdgb。 在這兩個應用程序中,我至今只能獲得錯誤解碼的utf8數據。 另一方面,我曾經在一個Windows平臺 上eclipse中調試過一個java項目,並且所有內部字符串都被正確顯示(但是這個應用程序不是使用我們的lib和相應的字符串的 ),因此至少在某些情況下,eclipse可以使用 顯示unicode字符正確。

最討厭的點對我來說,到目前爲止我甚至不能拿出 任何證據,這顯示真正的Unicode數據(即非ISO字符)是Linux在任何安裝工作 (即連GDB爲將QString腳本我發現,似乎 只顯示拉丁字符,並跳過其餘的),但當然 的幾乎每一個Linux應用程序似乎支持Unicode數據,從而有 必須被周圍的人,在Linux平臺,調試真正的Unicode數據 ,我真的無法想象,他們都是讀書hexcodes,而不是直接 顯示unicode字符串。

因此,任何指向允許調試unicode字符串的設置的指針,基於任何其他字符串類(f.e.QString)和/或IDE的 也將被理解。

+0

我剛剛嘗試在命令行上使用普通的 gdb調試我的應用程序,並且這顯示至少有一個我正確測試的(我在gdb和konsole設置中使用utf-8字符集)測試的一個 漢字字符。 因此,這減少了上述問題,我怎麼能在任何IDE做同樣的 事情? – user209210 2009-11-12 12:02:11

+0

另一個有趣的觀察,當我嘗試在eclipse中打印utf-8或utf-32字符串時,拉丁字符被正確打印,非拉丁字符被轉義爲hexcode,即我沒有看到由編碼問題導致的常見ISO垃圾字符。這可能意味着要麼Ecl。或gdb確實正確解碼字符串,然後轉義非ASCII字符。正如之前所寫,對於控制檯編碼中的gdb,我設法查看正確的字符,因此這實際上看起來像eclipse正確解碼字符串並在發送到UI時將其轉義出來? 有沒有可能驗證或影響這個? – user209210 2009-11-12 15:29:22

+0

這聽起來像你在Eclipse中使用的字體沒有你感興趣的所有字符的字形。希望Eclipse可以讓你改變字體 - 找到一個你想要的字形... – caf 2009-11-13 01:43:28

回答

0

我假設你正在X?是否安裝了正確的字體?

如果在控制檯上,您使用的幀緩衝作爲終端設備? VGA文本模式最多隻能顯示256/512個字符。 (512 IIRC的情況下吃了一點的色彩空間的)

+0

是的,更確切地說,我現在在gnome上使用Ubunt 9.10。 我想使用圖形前端(Eclipse/kdbg/kdevelop/ddd ...),因此必須對其進行配置。基本上對於大多數IDE來說,查看utf-8編碼的源代碼似乎沒有問題,我可以看到當前字符集支持的所有字符,但在調試時,我只能獲得非ASCII字符的轉義十六進制代碼。 – user209210 2009-11-12 11:46:05

3

大多數Linux發行版往往有出色的Unicode支持。但是,我會說在Linux上使用UTF16是一個錯誤。我意識到這很自然,來自Windows環境,但它會讓你在Linux上更加困難。

只要你的位置設置爲Unicode,是微不足道的使用wprintfwcout輸出UTF-32字符串(wchar_t的字符串),當然你也可以使用正常的輸出設備輸出的UTF-8字符串。然而,UTF-16你基本上限於構建使用int16_t,其中,因爲你已經發現,將是很難在調試器來打印自定義字符串類。

你提到創建它轉換爲UTF-16 UTF-8進行調試的目的,功能,但是變長字符,很難對付。爲什麼不簡單地創建一個將UTF16轉換爲UTF32的函數,因此每個Unicode代碼點都是一個字符?這樣你可以使用寬字符輸出來讀取字符串。 GDB不允許默認輸出寬字符字符串,但您可以使用this simple script修復該字符串。

+1

我不確定使用UTF-16是否真的是一個錯誤,因爲32位字符可能會使我們的記憶足跡幾乎增加一倍,因此 對性能(這被認爲是我們的目的的關鍵部分)另一方面,32位字符集只能啓用額外的字符,我們很可能永遠不需要。 在仲裁登錄中記錄數據不成問題。 現在我調整好自己的轉儲方法UTF-32,並試圖把結果 到WCHAR,設定目標寬字符爲UTF-32在gdb,一遍 作品在控制檯中,但不是在工具KDbg。現在我會用其他IDE來測試這個。 – user209210 2009-11-12 12:53:58

+0

嗯,你說得對,UTF-32消耗了兩倍的內存。我通常的操作策略是將Unicode數據存儲爲UTF-8,如果我必須處理它,我首先將其轉換爲UTF-32。 – 2009-11-12 13:45:06

+0

剛剛嘗試在eclipse中將utf-32轉換爲wchar,結果看起來像 L「\ 344 \ 270 \ 203ABER」,即拉丁字符顯示正確, 但主導的漢字再次亂碼爲轉義的十六進制值... – user209210 2009-11-12 14:24:52

2

Charles Salvia上面提到的簡單腳本「wchar.gdb」幫助了我,但幾年後很難找到(鏈接在文章中斷),因此我將粘貼ist在這裏。該腳本還演示了gdb中內置的一些鮮爲人知的宏功能。

define wchar_print 
    echo " 

    set $i = 0 
    while (1 == 1) 
      set $c = (char)(($arg0)[$i++]) 
      if ($c == '\0') 
        loop_break 
      end 
      printf "%c", $c 
    end 

    echo "\n 
end 


document wchar_print 
wchar_print <wstr> 
Print ASCII part of <wstr>, which is a wide character string of type wchar_t*. 
end 
0

電流GDB dersions可以顯示16位寬的字符數據直接地: 如果程序不使用wchar_t的(32位)的數據類型在所有, 例如它使用寬數據類型UChar(16位)的ICU庫(Unicode的國際組件), 您可以將gcc選項-fshort-wchar設置爲無符號短整型,將wchar_t和寬字體(L「abc」,L'd') (16位)。 因此,不必調用wchar_t glibc函數。 如果目標程序中至少定義了一個wchar_t啞變量,則gdb可以顯示wchar_t(16位)字符數據。 示例GDB會話:

short-wchar.c: 
#include <wchar.h> 
wchar_t wchr; 
main() { printf("sizeof(L'a') = %d\n", sizeof(L'a')); return 0; } 
gcc -g -fshort-wchar short-wchar.c -o short-wchar 
# terminal session encoding utf-8 assumed 
gdb short-wchar 
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1 
    (gdb) show charset 
    The host character set is "auto; currently UTF-8". 
    The target character set is "auto; currently UTF-8". 
    The target wide character set is "auto; currently UTF-32". 
    (gdb) set target-wide-charset UTF-16 
    (gdb) p L"Škoda" 
    $1 = L"Škoda" 
    (gdb) p (wchar_t*) (some UChar string) 
    .... 

的一個原因爲在所有平臺上使用的16位的wchar_t是跨平臺的一致性, 見ICU,OCI(Oracle調用接口在寬模式)和Java數據類型char。