我一直在研究一個在專用Linux CentOS系統上工作正常的項目。在虛擬機中使用GDB來調試Python ctypes segfaults
總的想法是,有一個Python的工作流程管理器比用C寫的使用ctypes的調用共享庫。它工作正常。
然而,需要我有項目用於開發目的的本地實例已經上來了。我在Windows 7下設置了VMWare的Linux Mint虛擬機。大多數情況下,一切正常。
的問題是一個模塊與分段故障時調用的共享庫中的一個的功能崩潰。通常情況下,這是可以的,在專用的Linux機器上,使用諸如「gdb python corename」之類的東西,可以讓我確切地看到它墜毀的位置並解決問題。
但是,在本地設置我有問題。我最關注的是GDB不報告正確的內存地址。這是一個龐大的工程,所以我不能發佈所有的代碼,但我會給出一個破敗:
Python模塊創建一個「FILE_PATH」變量,一個字符串。它首先將它傳遞給某個共享庫來加載文件。如果我執行命令,在python
hex(id(file_path))
它會返回類似'46cb4ec'的東西。在第一個共享庫,它是C,I啓動它不與
printf("file_pathaddress = %x\n", &file_path[0]);
並輸出「FILE_PATH地址= 46cb4ec」,這是相同的我通過Python的「的id()」函數得到。我猜這是預期的...?
不管怎麼說..我這個相同的變量發送到另一個共享庫,但它在這一呼籲立即崩潰。如果我分析核心文件,它顯示它在函數調用本身上崩潰,而不是函數內的一行。奇怪的是,它的輸出是這樣的:
Program terminated with signal 11, Segmentation fault.
#0 0x00007f124448c9fc in seam_processor (irm_filename=<error reading variable: Cannot access memory at address 0x7fff5fab51b8>,
seam_data_path=<error reading variable: Cannot access memory at address 0x7fff5fab51b0>,
full_data_path=<error reading variable: Cannot access memory at address 0x7fff5fab51a8>, ranges=<error reading variable: Cannot access memory at address 0x7fff5fab51a0>,
job_id=<error reading variable: Cannot access memory at address 0x7fff5fab519c>, job_owner=<error reading variable: Cannot access memory at address 0x7fff5fab5198>,
y_tile_in=1, x_tile_in=1, fc_int=10650000000, atmos_props=..., surf_props=..., extra_props=<error reading variable: Cannot access memory at address 0x7fff5fab5190>,
gascalc_ftype=513, len_gas_sectrum=16, vect_spec_fq=<error reading variable: Cannot access memory at address 0x7fff5fab5188>, surfscat_theta_inc_vector_size=6,
surfscat_theta_inc_vector=<error reading variable: Cannot access memory at address 0x7fff5fab5180>, surfscat_phi_inc_vector_size=6,
surfscat_phi_inc_vector=<error reading variable: Cannot access memory at address 0x7fff5fab5178>, surfscat_theta_scat_vector_size=6,
surfscat_theta_scat_vector=<error reading variable: Cannot access memory at address 0x7fff5fab5170>, surfscat_phi_scat_vector_size=6,
surfscat_phi_scat_vector=<error reading variable: Cannot access memory at address 0x7fff5fab5168>) at src/seam_processor.c:47
所以,我不明白爲什麼GDB報告這些內存地址是這樣的。在這種情況下,'irm_filename'變量是Python作爲'file_path'傳入的內容,因此其地址應該是其他庫和id()函數報告的內容0x46CB4EC。爲什麼不同?然而,奇怪的是有些變量很好,比如'y_tile_in'。如果我在gdb:
所以,雖然它可以讀取該內存地址,這是不一樣的東西Python的ID()將報告,或者什麼類似C的printf()的地址將報告在一個不會崩潰的庫中。而且,這些內存地址真的很大,比我目前的內存量還要大......他們的真正含義是什麼?
那麼我的問題是這裏究竟發生了什麼?這是否正在虛擬機中運行?有一些映射正在進行嗎?我一直沒能找到任何關於網上一些不同的事情我不得不如果在虛擬機用gdb做的,所以我在虧損...
任何人都知道這是怎麼回事?
謝謝。
編輯
所以,這個問題已經變得陌生。基本上,我將庫中的所有代碼都註釋掉了,並且調用了相同的函數。當我這樣做並使用斷點在gdb中運行它時,它在函數調用中打印的所有內存地址都是正常的,匹配Python id()函數並匹配地址上的printf()。
我開始取消註釋代碼以查看問題的原因。問題是與聲明:
double nrcs_h_d[MAX_NINC_S*MAX_SCAT_S];
double nrcs_v_d[MAX_NINC_S*MAX_SCAT_S];
如果我註釋掉兩條線,沒有崩潰。如果我只評論第二行,那就沒有崩潰。如果沒有行被註釋掉,但它會崩潰。
奇怪的是,MAX_NINC_S和MAX_SCAT_S都等於500.所以,這些數組的大小隻有幾兆字節......其他幾百兆字節的代碼數組分配得很好。
另外,如果我用替換上述行:
double *nrcs_h_d, *nrcs_v_d;
nrcs_h_d = (double *)malloc(MAX_NINC_S*MAX_SCAT_S*sizeof(double));
nrcs_v_d = (double *)malloc(MAX_NINC_S*MAX_SCAT_S*sizeof(double));
這似乎很好地工作......因此很明顯,這個問題是有關試圖分配過多的堆棧。
所以,問題變成了:
爲什麼GDB沒有顯示這是那裏的分割發生故障的代碼行,而是說,這是函數調用?
爲什麼核心轉儲文件的內存地址似乎全部搞砸了?
謝謝。
僅在win7機器上的segfault還是兩者兼而有之?你用什麼版本的C編譯器來編譯C模塊? – 2012-08-15 19:48:37