因此,首先,我對 C 不太了解,我從前一段時間上的一門課中知道的很少。到目前為止,我所擁有的幾乎所有東西都來自這個非常慷慨和知識淵博的社區。
我必須使用一個古怪的自定義軟體才能在 MacOS 上作業,它沒有任何形式的自動保存功能,而且它偶爾會崩潰。雖然我經常保存,但由于崩潰而失去任何作業量都很煩人。
我想要做的是使用保存功能地址保存并每 5 分鐘左右重復一次。到目前為止,我有行程 id、行程的運行時基記憶體地址、保存函式地址的偏移量(我已經從除錯和反匯編中找到的地址中減去了反匯編器基地址)以及它需要的引數。當我嘗試運行保存功能時,我收到 lldb 錯誤 Thread 1: EXC_BAD_ACCESS (code=1, address=0x10a106ecf),有時它會更改為 Thread 1: EXC_BAD_ACCESS (code=2, address=0x10a106ecf)。我在本網站上發現了有關此錯誤的其他問題,但它要么不適用于我的情況,要么由于我的知識有限,我只是不明白如何為我的情況解決它。如果有人可以詳細解釋我做錯了什么以及解決方案,
該專案是 Xcode 中的命令列實用程式。我不確定它是否需要成為 .dylib 并添加到行程中,但如果它可以是外部命令列實用程式,那對我來說會更理想。
這是問題代碼:
mach_vm_address_t runtimeBase = 0; // Base process memory address. Set in the getProc() function
mach_vm_address_t funcBase = 0x973ECF; // Function Address from disassembling. (0x100973ECF - 0x100000000 = 0x973ECF)
int main()
{
if (!getProc()) throw std::logic_error("Failed to get Process.");
typedef mach_vm_address_t(__cdecl* autoSave)(int saveType, const char* saveMessage);
autoSave save = (autoSave)(runtimeBase funcBase);
for(;;)
{
save(0, "AutoSave");// <-- Error Here: Thread 1: EXC_BAD_ACCESS (code=1/2, address=0x10a106ecf)
//sleep(5); //add sleep after I get save to work.
}
}
/*
saveType:
0 = Save local.
1 = Save server.
saveMessage: Message for history/save log.
*/
我從 code=1 錯誤中得到的更多細節是:
error: memory read failed for 0x10a106e00 <-- Thread 1: EXC_BAD_ACCESS (code=1, address=0x10a106ecf)
對于 code=2 是:
0x10a106ecf: addb %al, (%rax) <-- Thread 1: EXC_BAD_ACCESS (code=2, address=0x10a106ecf)
0x10a106ed1: addb %al, (%rax)
0x10a106ed3: addb %al, (%rax)
0x10a106ed5: addb %al, (%rax)
0x10a106ed7: addb %al, (%rax)
0x10a106ed9: addb %al, (%rax)
0x10a106edb: addb %al, (%rax)
0x10a106edd: addb %al, (%rax)
0x10a106edf: addb %al, (%rax)
0x10a106ee1: addb %al, (%rax)
0x10a106ee3: addb %al, (%rax)
0x10a106ee5: addb %al, (%rax)
0x10a106ee7: addb %al, (%rax)
0x10a106ee9: addb %al, (%rax)
0x10a106eeb: addb %al, (%rax)
0x10a106eed: addb %al, (%rax)
uj5u.com熱心網友回復:
通過@Peter Cordes的組裝解釋,我設法解決了我的問題。
@Peter Cordes:
addb %al, (%rax)是如何00 00解碼的。那里崩潰表明執行跳轉到一些全為零的記憶體,可能是由于覆寫了回傳地址或函式指標。或者,如果您有任何手寫的 asm,因為堆疊出現問題。
@Peter Cordes:這
EXC_BAD_ACCESS (code=2, address=0x10a106ecf)是為了讀取和寫入 RAX 中的任何垃圾。00 00垃圾機器代碼解碼為嘗試訪問“壞指標”的指令。我根本沒有使用 LLDB 或 MacOS 進行開發,但我猜測 code=1 vs 2 可能是讀取與寫入。(而且我還沒有真正查看您問題的詳細資訊,只是想通過解釋在整個addb %al, (%rax)指令塊中看到執行意味著您跳轉到一個充滿零的區域來提供幫助;它嘗試的任何記憶體訪問都是虛假的。 )
因此,正如@Peter Cordes所說 ,解碼addb %al, (%rax)方式是這樣的。00 00在那里崩潰表明執行跳轉到了一些全為零的記憶體。
由此我們可以推斷,Thread 1: EXC_BAD_ACCESS (code=2, address=0x10a106ecf)發生這種情況是因為我們跳轉到了記憶體中一個全為零的地方。但是為什么我們要跳轉到記憶體中全為零的地方呢?我認為這是因為 MacOS 處理記憶體的方式。每個行程都有自己的記憶體空間,我試圖跳轉到0x10a106e00MY OWN 行程記憶體中不存在的地址。有大量資源解釋了行程記憶體在現代作業系統上的作業原理,如果您想了解更多資訊,只需進行快速谷歌搜索即可。
所以我們現在知道的是:
Thread 1: EXC_BAD_ACCESS (code=1, address=0x10a106ecf)發生是因為我的程式無法讀取指定地址的記憶體。Thread 1: EXC_BAD_ACCESS (code=2, address=0x10a106ecf)發生是因為我們在記憶體中跳轉了一個無效的位置,并且是為了錯誤的行程。
代碼也存在一些問題,我使用的是更適合 Windows 的代碼,要根據我所做的記憶體地址創建一個函式,
typedef mach_vm_address_t(__cdecl* autoSave)(int saveType, const char* saveMessage);
autoSave save = (autoSave)(runtimeBase funcBase);
這就是我認為基于記憶體地址創建函式的更好/正確的方法是:
int (*autoSave)(int saveType, const char* saveMessage) = (int (*)(int , const char *))(runtimeBase funcBase);
我做的最后一件事是創建 Dylib 而不是命令列實用程式。我這樣做是因為訪問目標行程的記憶體要容易得多。雖然我試圖實作的目標可能是通過命令列實用程式(CLU)并附加到目標行程,就好像 CLU 是除錯器或其他方法一樣,但對我來說,創建一個 dylib 更加簡單和容易。
如果有人閱讀本文對我的解釋有任何疑問,或者想要更詳細的解釋/我的解決方案示例。隨時給我發訊息或評論。
我再次感謝@Peter Cordes的解釋。盡管他們說“我根本沒有使用 LLDB 或 MacOS 進行開發”,但他們還是提供了幫助。這些解釋仍然非常有幫助,并且以易于理解的方式進行了解釋。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459716.html
下一篇:RISC-V遞回函式除錯
