MTK調試入門之一------TRACE使用的技巧

52RD上曾有朋友讓我寫一些調試技巧方面的文章.調試對於軟件是十分重要的,但卻不是一篇二篇文章能講清楚的.有不少調試技巧都是零零碎碎的東西,用的時候能很容易使用,但要寫出來時,卻仍是比較麻煩的.html

MTK的調試通常來講能夠分爲仿真調試與手機調試.這兩種調試對於研發新功能,修改BUG,研究算法都是十分重要的.固然,這兩種調試也有差別,有時會出如今模擬器運行正常,在手機卻運行失敗,或者相反,這就突出了軟件模擬環境與硬件手機環境的差異.緣由多是各類各樣的,好比多是有些硬件軟件沒有辦法模擬,有些新功能對硬件依賴強,不能模擬,新軟件的有些函數只能在手機上運行,沒有寫相應的模擬器代碼.等等緣由都會致使二者差別.這裏不一一贅述,你們知道模擬器和手機有差別就好了.算法

模擬器調試具備直觀,快速,追蹤方便能優勢,受到不少MMI開發者的喜歡.而有關模擬器的調試,其餘也就是VC調試功能的使用.因爲國內軟件教育重編程,算法,輕調試,因此不多有系統的調試方書的書.在開發過程當中,我也見過許多人壓根就不使用模擬器,他們認爲模擬器也就是在沒有手機的時候使用.詳細講解模擬器的調試就放到之後,由於模擬器斷點,內存,堆棧,變量各個方面的調試,詳細寫來均可以成一篇文章.這裏先講一個手機調試的TRACE使用.之前曾寫過一篇DUMP調試的文章.經過出錯的DUMP信息查找錯誤.有興趣的朋友能夠參考. Detail_RD.Blog_blogercn_19169.html編程

 

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_Pui

    char    str[2048];編碼

    char   *ptr = (char*)str;.net

    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語言的古怪用法,據 的做者曾說,世界上有一個古怪的大賽叫」國際C語言混亂代碼大賽」,每一年舉辦一次.獲獎的都功能齊全而代碼慘不忍睹的典型.在MTK上,也曾經有一段費了我很大功夫的TRACE代碼:

#define DBG_PRINTF(_x_) \

do{ \

printf("%s(%d)--:",__FILE__,__LINE__);\

printf  _x_; \

}while(0);

當時怎麼想都不明白爲何會有這麼古怪的使用printf  _x_;後來才發現使用時要加雙層括號才能正常使用。

6.在手機與網絡,手機與電腦的交互過程當中,有時咱們須要TRACE數據包的內容,特別在顯示不正確或者不精確的狀況下,須要研究數據包的數據是使用UTF編碼,還UCS2編碼,仍是ASC編碼,這時咱們就須要TRACE數據的字節內容,從而便於分析。我通常使用下面這個本身隨手寫的函數來實現.


static U8 TraceUni(U8 *str, U8 len)
{
 U8 *tempstr,*tempascstr;
 U8 i;
 
 tempstr = str;
 kal_prompt_trace(MOD_MMI, "XXXXXXXXXXXXXXXXXXXXXXXX   Trace mmi_msg_handle_new_msg_ind is start    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
 if (*(tempstr + 1) == 0x00)
 {
  UnicodeNToAnsii((S8*)tempascstr,(S8*)tempstr,len );
  kal_prompt_trace(MOD_MMI, "jone trace, the string = %s", tempascstr);
 }
 else
 {
  for (i = 0; (*tempstr != NULL) || (*(tempstr+1) != NULL) && (len-- != 0); i++)
  {
   kal_prompt_trace(MOD_MMI, "jone trace, the string[%d] = %x", i, *(tempstr++));
  }
 }
 kal_prompt_trace(MOD_MMI, "XXXXXXXXXXXXXXXXXXXXXXXX   Trace string is end      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
 
 return 0;
}

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/blogercn/archive/2009/10/28/4739732.aspx

相關文章
相關標籤/搜索