[Python] 出現 undefined symbol: PyUnicodeUCS4_AsEncodedString 錯誤

[Python] 出現 undefined symbol: PyUnicodeUCS4_AsEncodedString 錯誤

很久之前寫過一篇 自己編譯 Wide python 解決 Narrow python 的問題

沒想到最近因為專案支援的另外一個產品在換平台,

因此又踩到了 narrow-python 的雷…

 

狀況是這樣的,他們從原本 CentOS 5.4 的 python 2.6,升級到 CentOS 7 的 python 2.7,

整合我們的東西的時候,就出現 pycurl 的錯誤:

>>> from tool.pycurl import pycurl
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: tool/pycurl/pycurl.so: undefined symbol: PyUnicodeUCS4_AsEncodedString

 

看起來是 pycurl.so 想要呼叫 PyUnicodeUCS4_AsEncodedString 這個函式,但是找不到,

可是以前他們用 python 2.6 的時候沒有這個問題…

而有另外一個產品也是用 CentOS 7 的 python 2.7,與我們整合時也沒有出現問題。

所以是怎麼一回事呢?

 

後來爬文得到一些靈感,分別檢查一下壞掉的那個產品的 python 與好的 python,

裡面的 PyUnicodeUCS 函式有哪些,果然發現壞掉的只有 PyUnicodeUCS2_AsEncodedString,

而好的那個就有我們需要的 PyUnicodeUCS4_AsEncodedString:

root@bad-python ~ $ nm -D /usr/lib64/libpython2.7.so | egrep "PyUnicodeUCS.*_AsEncodedString"
00000000000d71e0 T PyUnicodeUCS2_AsEncodedString
root@good-python ~ $ nm -D /lib64/libpython2.7.so.1.0 | egrep "PyUnicodeUCS.*_AsEncodedString"
00000000000b7da0 T PyUnicodeUCS4_AsEncodedString

 

推想了一下,應該是我們自己在 CentOS 5.4 編譯 pycurl 時,

使用到系統預設的 python,而這系統預設的 python 是所謂的 narrow-python,

只有定義 PyUnicodeUCS2_AsEncodedString,

而出問題的外部產品在升級前用的 python 也是 narrow-python,所以沒問題。

 

但當升級到 CentOS 7 之後,我們使用系統預設的 wide-python 來編譯 pycurl,

但出問題的外部產品還是編譯出了 narrow-python,

導致 pycurl 想呼叫 PyUnicodeUCS4_AsEncodedString 卻找不到…

 

除了用 nm 查 export 出來的函式之外,

另一個檢查方法就是看 unichr(0x10000) 會不會有錯誤,有的就是 narrow-python:

>>> unichr(0x10000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unichr() arg not in range(0x10000) (narrow Python build)

 

或是看 sys.maxunicode 的值,65535 的就是 narrow-python:

>>> import sys
>>> sys.maxunicode
65535

 

通知出問題的外部產品,在編譯 python 2.7 時,

加上 ./configure –enable-unicode=ucs4,就解決問題囉~

再次檢查這次編譯出來的 python,可以支援 unichr(0x10000),

sys.maxunicode 也可以達到最大值 0x10FFFF,的確是 wide-python 沒有錯:

>>> unichr(0x10000)
u'\U00010000'
>>> import sys
>>> hex(sys.maxunicode)
'0x10ffff'

 

參考資料: 

How to find out if Python is compiled with UCS-2 or UCS-4?

Weird “undefined symbol: PyUnicodeUCS{2|4}_AsEncodedString” errors

 

(本頁面已被瀏覽過 1,818 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料