簡體   English   中英

在虛擬機中使用GDB調試Python ctype segfaults

[英]Using GDB in a virtual machine to debug Python ctypes segfaults

我一直在從事一個在專用Linux CentOS系統上運行良好的項目。

通常的想法是,有一個Python工作流管理器可以調用使用ctypes用C編寫的共享庫。 工作正常。

但是,出於開發目的,我需要擁有該項目的本地實例。 我在Windows 7下使用VMWare設置了Linux Mint虛擬機。在大多數情況下,一切正常。

問題是一個模塊在調用共享庫之一中的函數時因分段錯誤而崩潰。 通常這是可以的,並且在專用的Linux計算機上,使用諸如“ gdb python corename”之類的內容,可以讓我確切地看到崩潰的位置並解決問題。

但是,使用本地設置時,我遇到了問題。 我最注意的是GDB沒有報告正確的內存地址。 這是一個巨大的項目,因此我無法發布所有代碼,但是我將給出一個總結:

Python模塊創建一個“ file_path”變量,即一個字符串。 它首先將其傳遞給某個共享庫以加載文件。 如果我執行命令,在python中

hex(id(file_path))

它將返回類似“ 46cb4ec”的內容。 在第一個共享庫C中,我從

printf("file_pathaddress = %x\n", &file_path[0]);

並輸出“ file_path address = 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中這樣做:

(gdb) print &y_tile_in
$1 = (int *) 0x7fff60543f80

因此,盡管它可以讀取此內存地址,但這與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沒有顯示這是發生分段錯誤的代碼行,而是說這是函數調用?

如果進行了分配,為什么核心轉儲文件的內存地址似乎被搞砸了?

謝謝。

回想一下,堆棧空間向下增長,而堆空間向上增長; 靠近虛擬內存空間頂部的地址(例如0x7fff5fab51b0 )是堆棧分配的變量,而靠近底部的地址(例如0x46cb4ec )是堆分配的變量。 請注意,虛擬內存空間通常比物理內存大得多; 看起來您的操作系統和體系結構最多支持128 GiB虛擬內存。

由於Python在很大程度上取決於動態內存分配,因此最終它將把其對象放在堆上,這就是為什么id()傾向於在低端返回地址的原因。 如果C代碼將任何值復制到堆棧分配的變量中,然后嘗試使用這些本地副本調用函數,則將再次在高端看到地址。

提供了一個行號: src/seam_processor.c:47 那里有什么有趣的嗎? GDB抱怨的各種內存地址是堆棧上的各種內存地址,它們都是順序的,並且幾乎所有它們自己都似乎是指針(因為它們都是8字節寬)。

(這是我可以利用現有信息提供的最佳答案;請隨時提出修改建議或提供其他信息。)

一種可能的解釋是,在執行特定功能中的任何代碼之前,會為功能中的局部變量分配數據。

編譯器會計算出所需的堆棧空間量,並在進入函數中的語句之前對其進行分配。 因此,函數的實際執行如下所示:

  1. 為所有局部函數變量分配存儲量,
  2. 開始執行函數中的語句

這樣,當您從fucntion1調用另一個say function2時,function1的局部變量將不會受到來自function2中的局部變量的數據的干擾。

因此,在您的情況下,本地數據變量所需的空間超過了堆棧可用的空間,並且在函數代碼開始執行之前的某個時間點引發了異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM