52rd上曾有朋友讓我寫一些除錯技巧方面的文章.除錯對於軟體是十分重要的,但卻不是一篇二篇文章能講清楚的.有很多除錯技巧都是零零碎碎的東西,用的時候能很容易使用,但要寫出來時,卻還是比較麻煩的.
mtk的除錯一般來說可以分為**除錯與手機除錯.這兩種除錯對於研發新功能,修改bug,研究演算法都是十分重要的.當然,這兩種除錯也有差異,有時會出現在模擬器執行正常,在手機卻執行失敗,或者相反,這就突出了軟體模擬環境與硬體手機環境的差別.原因可能是各種各樣的,比如可能是有些硬體軟體沒有辦法模擬,有些新功能對硬體依賴強,不能模擬,新軟體的有些函式只能在手機上執行,沒有寫相應的模擬器**.等等原因都會導致兩者差異.這裡不一一贅述,大家知道模擬器和手機有差異就行了.
1.在mtk平台,我們最常使用的trace函式是kal_prompt_trace函式,這個函式是系統提供給我們的用於在catcher裡除錯錯誤的.在這個函式不能使用的場合,有時我們會使用函式system_print或者dbg_printf,這兩個函式可以不使用catcher的情況,使用win自帶的工具超級終端來除錯程式.有時驅動的朋友會自己用函式putuartbytes寫自已trace函式,這些函式可以使用超級終端除錯,如下,就是別人寫的乙個trace函式.列印某一塊資料的內容,常常trace記憶體資料,指定位址,指定大小
void perun_dump(void *buf, prn_int16 size)
#ifdef prn_trace_open
#ifdef mmi_on_hardware_p
char str[2048];
char *ptr = (char*)str;
char *ptr1 = buf;
int i = 0;
memset(str, 0, sizeof(str));
strcpy(ptr, "[perun_dump]: ");
ptr += strlen("[perun_dump]: ");
while (i < size)
sprintf(ptr, " %02x", *ptr1);
ptr += 3;
++ptr1;
++i;
sprintf(ptr, "\r\n");
putuartbytes(0, (kal_uint8 *)str, (kal_uint16)strlen(str));
#endif
#endif
也可以寫乙個像mtk自帶的一樣的函式來trace,如下,該函式也是可以執行在終端中:
void perun_trace(char *fmt, ...)
#ifdef prn_trace_open
#ifdef mmi_on_hardware_p
va_list list;
char buf[2048];
char *ptr = (char*)buf;
memset(buf, 0, sizeof(buf));
strcpy(ptr, "[perun_trace]: ");
ptr += strlen("[perun_trace]: ");
va_start(list, fmt);
vsprintf(ptr, fmt, list);
va_end(list);
strcat(buf, "\r\n");
buf[2047] = 0;
putuartbytes(0, (kal_uint8 *)buf, strlen(buf));
#endif
#endif
2.trace語句的編寫是十分重要的.如何寫出的trace既能在**下使用,也能在手機中使用,我一般會使用如下的格式:
#ifdef win32
#define mytrace printf
#else
#define mytrace(...) kal_prompt_trace(mod_wap, __va_args__)
#endif
經過如下的封裝,mytrace就可以既能在手機上執行,也能在電腦中執行, 並且我已經消除了mtk自帶的函式與printf在呼叫上的不同.順便說一下,模擬器呼叫函式mytrace時,會在控制制輸出該函式的列印資訊.手機呼叫mytrace時,會在filiter為mod_wap時輸出資訊.
3.有時為了便於觀察,我會為我的trace語句新增乙個字首,比如我自己的trace前面新增十個》或者我自己的拼音名字,我會如下修改我的mytrace:
#ifdef win32
#define mytrace printf
#else
#define str(s) #s
#define mytrace(...) kal_prompt_trace(mod_wap, str(>>>>>>>>>>)##__va_args__)
#endif
經過這樣的改進,我的trace在輸出資訊時,資訊頭就是我的名字,我可以使用查詢全部功能把我需要的trace全抓出來.如果你對#號的使用,有疑問,請自己查詢相關資料
4.種種跡象和從理論上看來,trace和mmi_assert是除錯的好幫手,但在發布軟體時,帶上了這個會引來不必要的麻煩.mmi_assert增加了系統重啟的頻率.trace增加了系統的rom,ram和cpu的開銷.在工作中,我們曾經發現一款手機,由於rom過於緊張,新增幾條trace就會出現編譯錯誤,去掉trace就編譯通過了,導致出了bug除錯十分的麻煩.如何寫一種使用時可以trace錯誤,不使用時又不占用系統資源的trace呢,我見許多人這樣處理,因為null會被編譯器優化點,後面括號變成乙個表示式了.表示式對系統的開銷自然小於函式了.
#ifdef debug_kal
#define mytrace(...) kal_prompt_trace(mod_wap, __va_args__)
#else
#define mytrace null
#endif
我一般這樣操作.
#ifdef debug_kal
#define mytrace(...) kal_prompt_trace(mod_wap, __va_args__)
#else
#define mytrace //
#endif
我曾經認為這樣寫可以在不使用時,把巨集函式變為注釋符,但我的乙個朋友認為這樣寫,並不能把我的函式變成注釋符,他的道理是雙斜線會被編譯器外忽略掉,我認為是有道理的,後來我的朋友經過思考,寫出如下的trace,通過乙個反斜槓的連線符,哄編譯器在展開巨集時把兩個斜槓連起來組成注釋符,這個寫法有些古怪,下面的單個斜槓必須頂格寫,以保證經過連線合,兩斜槓之間沒有空格從而在被編譯時與後面的**組成注釋行.但這樣寫的乙個致命的缺陷是會讓許多人看不明白.另乙個缺陷時不美觀
#ifdef debug_kal
#define mytrace printf
#else
#define mytrace /\
#endif
5.有關c語言的古怪用法,據#define dbg_printf(_x_) \
dowhile(0);
當時怎麼想都不明白為什麼會有這麼古怪的使用printf _x_;後來才發現使用時要加雙層括號才能正常使用。
6.在手機與網路,手機與電腦的互動過程中,有時我們需要trace資料報的內容,特別在顯示不正確或者不精確的情況下,需要研究資料報的資料是使用utf編碼,還ucs2編碼,還是asc編碼,這時我們就需要trace資料的位元組內容,從而便於分析。我一般使用下面這個自己隨手寫的函式來實現.
static u8 traceuni(u8 *str, u8 len)
else
}kal_prompt_trace(mod_mmi, "************************ trace string is end ************************************xx");
return 0;
}
MTK除錯入門之一 TRACE使用的技巧
zzjltx 發表於 2009 12 23 11 49 00mtk除錯入門之一 trace使用的技巧 懶書生 發表於 2009 10 29 20 13 00 52rd上曾有朋友讓我寫一些除錯技巧方面的文章.除錯對於軟體是十分重要的,但卻不是一篇二篇文章能講清楚的.有很多除錯技巧都是零零碎碎的東西,用...
MTK除錯入門之一 TRACE使用的技巧
mtk的除錯一般來說可以分為 除錯與手機除錯.這兩種除錯對於研發新功能,修改bug,研究演算法都是十分重要的.當然,這兩種除錯也有差異,有時會出現在模擬器執行正常,在手機卻執行失敗,或者相反,這就突出了軟體模擬環境與硬體手機環境的差別.原因可能是各種各樣的,比如可能是有些硬體軟體沒有辦法模擬,有些新...
Nginx入門之一
對於nginx早已耳聞,也已看好好多人對此元件的誇讚,效能是如何如何的好 但是一直沒有去看這方面的資料。今天興致來了,就研究了一番,不過並沒有什麼測試資料,只是在本地跑通了而已,因為我家只有乙個電腦也沒有裝虛擬機器,所以就出來了下面的配置檔案。今天算是乙個入門,接下來會詳細了解一下。以下是我本地的n...