MTK除錯入門之一 TRACE使用的技巧

2021-05-22 06:28:55 字數 3989 閱讀 2542

zzjltx 發表於 2009-12-23 11:49:00mtk除錯入門之一------trace使用的技巧

懶書生 發表於 2009-10-29 20:13:00

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使用的技巧

52rd上曾有朋友讓我寫一些除錯技巧方面的文章.除錯對於軟體是十分重要的,但卻不是一篇二篇文章能講清楚的.有很多除錯技巧都是零零碎碎的東西,用的時候能很容易使用,但要寫出來時,卻還是比較麻煩的.mtk的除錯一般來說可以分為 除錯與手機除錯.這兩種除錯對於研發新功能,修改bug,研究演算法都是十分重要...

MTK除錯入門之一 TRACE使用的技巧

mtk的除錯一般來說可以分為 除錯與手機除錯.這兩種除錯對於研發新功能,修改bug,研究演算法都是十分重要的.當然,這兩種除錯也有差異,有時會出現在模擬器執行正常,在手機卻執行失敗,或者相反,這就突出了軟體模擬環境與硬體手機環境的差別.原因可能是各種各樣的,比如可能是有些硬體軟體沒有辦法模擬,有些新...

Nginx入門之一

對於nginx早已耳聞,也已看好好多人對此元件的誇讚,效能是如何如何的好 但是一直沒有去看這方面的資料。今天興致來了,就研究了一番,不過並沒有什麼測試資料,只是在本地跑通了而已,因為我家只有乙個電腦也沒有裝虛擬機器,所以就出來了下面的配置檔案。今天算是乙個入門,接下來會詳細了解一下。以下是我本地的n...