簡體   English   中英

如何調試分段錯誤?

[英]How to debug segmentation fault?

在循環中,當我將每個元素都設置為0或entry_count-1時,它會起作用。 當我將它設置為使entry_count較小時,它可以工作,並且我用手寫而不是通過循環(sorted_order [0] = 0; sorted_order [1] = 1; ...等)編寫它。

請不要告訴我如何解決我的代碼。 出於非常特殊的原因,我不會使用智能指針或向量。 而是關注以下問題:哪種情況會導致此段錯誤? 謝謝。

----舊-----

我正在嘗試調試在Unix機器上無法正常工作的代碼。 代碼的要點是:

int *sorted_array = (int*)memory;
// I know that this block is large enough
// It is allocated by malloc earlier

for (int i = 0; i < entry_count; ++i){
  sorted_array[i] = i;
}

循環中某處似乎存在段錯誤。 不幸的是,切換到調試模式會使segfault停止。 使用cout調試,我發現它必須在循環中。

接下來,我想知道段錯誤發生在循環中的距離,因此我添加了:

std::cout << i << '\n';

它顯示了應該循環的整個范圍,並且沒有段錯誤。

經過更多的實驗,我最終在循環之前創建了一個字符串流,並為循環的每次迭代向其中寫入一個空字符串,並且沒有段錯誤。

我嘗試了其他各種操作,試圖弄清楚發生了什么。 我嘗試設置一個變量j = i; 諸如此類的東西,但是我還沒有發現任何有效的方法。

運行valgrind時,我得到的關於段錯誤的唯一信息是“常規保護錯誤”以及有關默認響應11的信息。它還提到有條件跳轉或移動取決於未初始化的值,但請看代碼我不知道這怎么可能。

這會是什么? 我沒有想法去探索。

這顯然是程序中內存使用無效的症狀,很難通過查看代碼片段來發現,因為這很可能是已經發生的其他不良情況的副作用。

但是,正如您在問題中提到的那樣,您可以使用Valgrind附加程序 因為它是可復制的 因此,您可能需要附加程序(a.out)。

$ valgrind --tool = memcheck --db-attach = yes ./a.out

這樣,當檢測到第一個內存錯誤時,Valgrind會將程序附加到調試器中,以便您可以進行實時調試(GDB)。 這應該是理解和解決問題的最佳方法。

一旦能夠找出第一個錯誤,就將其修復並重新運行,然后查看您還遇到了其他錯誤。應該執行此步驟,直到Valgrind報告沒有錯誤為止。

但是,您應該避免在現代C ++程序中使用原始指針,而應像其他人建議的那樣開始使用std::vector std::unique_ptr

Valgrind和GDB非常有用。

我使用的最早的版本是GDB,我喜歡它,因為它向我顯示了Segmentation Fault所在的確切行號。

以下是一些可以指導您使用GDB的資源:

GDB教程1

GDB教程2

如果您仍然不知道如何在這些教程中使用GDB,那么Google上有很多內容! 只需使用GDB搜索調試分段錯誤!

祝好運 :)

很難,我用valgrind工具調試段錯誤,它通常指出違規情況。

您的問題可能是釋放了您正在寫入的內存,即sorted_array超出范圍或被釋放。 隨着數據分配的轉移,添加更多代碼將隱藏此問題。

經過幾天的試驗,我弄清楚了到底發生了什么。

由於某些原因,機器會在未對齊訪問時發生故障。 也就是說,我正在寫入的整數沒有被寫入四個字節的倍數的內存邊界。 在循環之前,我計算了偏移量並將數組上移了這么多:

int offset = (4 - (uintptr_t)(memory) % 4) % 4;
memory += offset;

完成此操作后,所有操作均恢復了預期。

暫無
暫無

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

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