跳轉到內容

PSP 開發/基本錯誤處理

75% developed
來自華夏公益教科書,開放的書籍,開放的世界

隨著程式複雜度的增加,PSP 上潛在的錯誤數量呈指數級增長。C 語言能夠在效能受限的系統上開發功能性程式。PSP 是一款功能強大的裝置,與 PS2 的效能相當,而 PS Vita 的效能則超過 PS2。作為一款遊戲機,它對未定義行為、錯誤分配的資料、不正確的指標運算以及空指標非常敏感,這比電腦更嚴重。問題源於遊戲機是嵌入式的,以特定的方式執行,沒有使用者自制軟體開發的能力。有一個專有的系統專為生產力和除錯環境而設計。

注意 所有未來的文章都將使用以下函式。

錯誤處理策略

[編輯 | 編輯原始碼]

執行時錯誤是最容易處理的。執行時錯誤發生在系統對資料進行操作時,其結果返回不正確或對無效資料(頁面/段錯誤)進行操作。程式設計師有責任正確編寫程式,以便執行時錯誤不存在或在系統無法繼續執行的情況下進行處理。如果能夠有幸編寫物理 UMD 光碟,那麼程式設計師在處理諸如讀取時玩家取出光碟、無法讀取、掉落 PSP 等等情況時,就會顯得無能為力。在使用 UMD 的應用程式中,一個示例錯誤可能是使用者在讀取 UMD 時將其取出。程式需要提醒使用者操作已取消並返回到正常狀態。

C 編譯器錯誤

[編輯 | 編輯原始碼]

在 Python 和 Java 中,程式設計師會熟悉 try catch 語句。但是,C 語言有自己的處理方式。 C 語言中的錯誤處理 文件記錄了一些錯誤檢查策略。重要的是要理解文章中給出的建議之外的內容。在 #PSPDEV 錯誤 中,未定義幾乎可以直接作為 C 錯誤的同義詞。C 錯誤往往會在執行時完全崩潰。應該使用一種方法來確定問題所在。C 錯誤和 PSPDEV 錯誤之間的區別在於,使用庫的正確性與語法或記憶體相關問題之間的區別。新增到其他語言中的 try-catch 系統是錯誤的普遍性和執行時錯誤處理策略的產物,它將中斷的生產力轉變為生產力。

PSPDEV 錯誤

[編輯 | 編輯原始碼]

執行時錯誤有三種不同的模式:預期、意外和未定義。預期錯誤可能發生在系統檢查檔案是否存在以載入到系統中時。系統將返回一個狀態。意外錯誤可能發生在檔案中的資料損壞時 - 程式無法使用此檔案。系統無法立即檢測到這一點,否則可能會崩潰。這兩個錯誤都意味著程式無法繼續執行請求的操作。與繼續使用不正確的資料(可能會導致空指標和資料對齊錯誤)相比,一種解決方案是停止操作並提醒使用者。未定義錯誤是指編寫了語法上正確且理論上正確的程式碼,但會導致崩潰。例如,釋放分配的記憶體並將指標設定為 0,然後嘗試使用該變數指標可能會導致程式崩潰。意外錯誤和未定義錯誤之間的區別在於,未定義錯誤不會進入可以發生意外錯誤的階段。

預期和意外錯誤

[編輯 | 編輯原始碼]

在 PSPDEV 中,許多函式返回一個 int,它表示特定值的錯誤。有些程式透過圖形庫將錯誤顯示給使用者。在 main.c 中,有一個功能位置可以放置單個幫助程式函式,這些函式接受常用引數,並將它們顯示給使用者。本文介紹了一種在發生崩潰的情況下,以一種乾淨的方式處理錯誤的方法。這樣做的原因可以追溯到,無法制作一個“一勞永逸”的錯誤檢查函式,同時還要能夠繞過它們,以便程式仍然能夠正常工作。try-catch 語句的誕生正是由於這個問題,它能夠檢查和監聽預期或意外錯誤,並且程式有關於如何繞過它們的指令。C 語言沒有 try-catch 語句,因此本文旨在介紹一種更具創意的方式來處理錯誤。

以下函式的工作原理是,它圍繞著 main() 函式中的任何位置的主執行緒。由於除錯模式通常在主執行緒上執行,該執行緒使程式保持活動和更新,因此直接在每個列印的新行末尾寫入錯誤訊息,並無限期地掛起主執行緒以使其崩潰是有意義的。這使得能夠讀取錯誤訊息。可以透過提供一個具有相關通用錯誤處理引數的方法來實現回撥系統(而不是掛起執行緒以處理類似於 try-catch 的錯誤)。最好確保 vblank 以便能夠在任何地方呼叫此函式。以下函式最適合預期和意外錯誤。

main.c

void crash(int error, const char* crasher, const char* message) {
	sceDisplayWaitVblankStart();
	printf("Error (%d) : %s\n", error, crasher);
	printf("%s\n", message);
	sceKernelSleepThread();
}

未定義錯誤

[編輯 | 編輯原始碼]

PSP 最大的缺陷是崩潰時沒有輸出。需要實現一個工具來幫助找出潛在的未定義錯誤。除此之外,還需要模擬強制崩潰。因為一行程式碼可能會崩潰,在它之前輸出文字並掛起執行緒會導致沒有崩潰和文字顯示。但是,如果嘗試在崩潰程式碼行之後列印,執行緒將不會掛起,也不會顯示任何文字。利用這種邏輯,可以將列印-掛起函式移到可疑程式碼行周圍,以瞭解哪一行程式碼導致崩潰。但是,修復並不簡單,因為之前的行可能會造成崩潰程式碼行崩潰的原因。

以下程式碼是預期和意外錯誤函式程式碼的衍生,但內容更少。幾乎沒有有用的邏輯輸出可以輸出。但是,如果有必要,可以新增引數,但這會增加填寫引數的複雜性。相反,當找到崩潰的行時,列印相關的變數可能會節省時間和精力。這樣做也有助於進一步識別問題。對於未找到的錯誤進行 printf 操作,需要檢查與崩潰無關的變數的值。

main.c

void test_crash() {
	sceDisplayWaitVblankStart();
	printf("No crash occured.");
	sceKernelSleepThread();
}

高階錯誤處理

[編輯 | 編輯原始碼]

使用 pspDebug,可以安裝一個充當錯誤處理程式的函式。有了錯誤處理程式,就會有 PSP 的輸出。這有助於除錯發生了什麼。未來的文章可能會在某些情況下使用它,例如有問題的示例。這就像帶 stderr 的 try catch 語句 - 當發生錯誤時,會收集資料並說明問題。


工作示例

[編輯 | 編輯原始碼]


華夏公益教科書