這讓我感到非常緊張。我剛剛第一次將我的第一個應用程序上傳到App Store,當然,現在我的應用程序正在左右爆炸。當我使用發佈版本配置構建時,我在應用程序上敲擊了一段時間後隨機獲得EXC_BAD_ACCESS
。我重新打開殭屍,但問題似乎沒有過度釋放一個變量,因爲我沒有收到關於向釋放變量發送消息的消息。EXC_BAD_ACCESS,但沒有殭屍,也沒有在調試版本配置中
該錯誤總是出現在我的代碼中的相同位置。它看起來像我試圖保留一個尚未正確初始化的變量。我沒有絲毫的想法,我該怎麼做。
但是,這裏有一個奇怪的事情:如果我構建調試版本配置,它永遠不會崩潰。我可以整天砰砰作響,它堅如磐石。我使用Release配置進行構建,並且它會間歇性地崩潰。
查看兩種配置中的「生成」設置,沒有太多差異。在調試中,GCC 4.0優化級別是「無」,而在Release中,它是「最快,最小」。如果我將Release中的優化級別切換爲「無」,則該應用會自行運行。有沒有人有線索我應該尋找解決這個問題?或者,如果我沒有優化分配,會發生多少不好的事情?
UPDATE:
黨!我真的需要一個神奇的調試工具來處理內存錯誤。我在最後一天左右一直在處理這個問題。我添加了一個exercise
方法,可以可靠地生成崩潰並開始尋找導致它的代碼區域。
該應用程序通常會在第3-5次崩潰時執行一種特定類型的操作。這種類型的操作唯一不同的是我從附件方法返回的價值。配件方法通常返回NSDecimalNumber
s值爲0-3,但是當我返回一個非整數值的NSDecimalNumber
時有一個特殊情況。我會測試附件方法尋找非整數值的結果。我改變了特殊情況,返回值爲-1的NSDecimalNumber
而不是非整數值,我不能再讓應用崩潰。
基本上,我所做的唯一的變化是從 [[NSNumber numberWithDouble:num] decimalValue]
開關 - >崩潰 到 [[NSNumber numberWithInteger:num] decimalValue]
- >沒有崩潰
這一點,但比這更復雜一些,但並不多。
現在,我很高興該應用程序不再崩潰,但我所做的更改並不能滿足我的信心,因爲舊代碼不會以任何方式「破碎」。所以,雖然我的應用程序不再崩潰,但並不是因爲我「修復」了它,而是隨機更改了一些東西,現在它可以正常工作。 8 ^(
UPDATE:
調試器不吐堆棧跟蹤,因爲它通常在程序崩潰時崩潰,所述調試控制檯輸出以下的作用:。
加載程序到調試器...
[...版權所有...]
This GDB was configured as "i386-apple-darwin".warning: Unable to read symbols for "/System/Library/Frameworks/UIKit.framework/UIKit" (file not found).
warning: Unable to read symbols from "UIKit" (not yet mapped into memory).
warning: Unable to read symbols for "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics" (file not found).
warning: Unable to read symbols from "CoreGraphics" (not yet mapped into memory).
Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/...', process 10066.
Re-enabling shared library breakpoint 1
Cannot access memory at address 0x4
Cannot access memory at address 0x4
(gdb)
你應該看看你的堆棧跟蹤。什麼是真正的崩潰?更改NSNumber導致崩潰的事實表明,您可能會在某處過度釋放NSNumber。 NSNumbers由類緩存;如果您過度釋放一個,您可以崩潰在代表相同數字的完全不同的對象上。我看到代碼在值爲2時工作,但在4時失敗,因爲「4」的NSNumber在系統中的其他地方被過度釋放。 – 2009-05-28 03:53:04
我在調試這個問題時遇到了一些問題。由於我不明白的原因,調試器和樂器都沒有給我提供我期望的信息。通常,當應用程序崩潰時,調試器只顯示主執行線程,沒有關於誰調用導致崩潰的方法的詳細信息。也許這是因爲問題只在編譯器優化代碼時才顯現出來,所以調試器將源代碼映射到目標代碼的時間更加困難。我相信它也不能幫助我的調試排序仍然有點根本。一如既往,我感謝您的協助。 – ChadK 2009-05-28 05:19:09
不過,您應該發佈堆棧跟蹤(特別是前幾幀)。即使它不包含任何代碼,它也可以提供有關問題出處的很多信息。在Cocoa,你經常會要求代表你在稍後時間以你的名義運行。 -autorelease是一個很常見的例子。當「稍後時間」崩潰時,沒有任何「代碼」會出現在堆棧中,但仍然是由於代碼中的錯誤。 – 2009-05-28 13:30:59