MySQL源码学习——DBUG调试
一、前言
???????? 在規模稍微大點的項目中,為了方便快速找到bug的所在,我們往往需要在代碼中加入一些調試用的代碼,比如加入一些printf,打印出一些重點的信息;加入assert,進行斷言判斷。這些比較隨意的調試代碼會使整個系統顯得比較凌亂。于是Fred Fish開發了一套用于嵌入代碼中的庫,開發人員只需要調用相應的函數即可加入調試信息。
??????? 對于MySQL這種多線程的程序來說,調試也是比較困難的,MySQL選擇了DBUG作為其調試代碼(在原始代碼的基礎上進行了略微的改造),充分說明了DBUG的實用性,本文就DBUG的原始代碼進行介紹。
二、DBUG下載與使用
?????? 這里以linux下的開發進行介紹。
????? 首先需要下載DBUG源碼,下載地址:http://sourceforge.net/projects/dbug/
????? 解壓后在dbug/src下即是debug所需的源碼文件:dbug.h dbug.c
????? dbug/example.c是一個簡單的例子,源碼如下:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /* ?* This file is Public Domain ?* ?* Just short example, how Fred Fish's dbug package should be used ?* ?* Tonu Samuel <tonu @spam.ee=""> ?* ?*/ #include "dbug.h" static?int?sub1 (void); static?void?sub2 (char?*arg); static?int sub1 (void) { ??DBUG_ENTER ("sub1"); ??sub2 ("Hello world!"); ??sub2 ("Hello earth!"); ??sub2 ("Hello programmer!"); ??DBUG_RETURN (0); } static?void sub2 (char?*arg) { ??DBUG_ENTER ("sub2"); ??DBUG_PRINT ("info", ("Got argument: '%s'", arg)); ??printf?("%s\n", arg); ??DBUG_VOID_RETURN; } int main (void) { ??int?ret = 0; ??DBUG_PUSH ("d:t:O"); ??DBUG_PROCESS ("example"); ??ret = sub1 (); ??DBUG_PRINT ("info", ("Returned value: %d", ret)); ??return?0; }</tonu> |
我們將example.c放到src目錄下,然后編譯example文件:
| 1 | dbug/src$?gcc?-Wall -g dbug.c example.c -o example |
運行example輸出如下:
| 1 2 3 4 5 6 7 8 9 10 11 | >sub1 | >sub2 | | info: Got argument:?'Hello world!' Hello world! | <sub2 |="">sub2 | | info: Got argument:?'Hello earth!' Hello earth! | <sub2 |="">sub2 | | info: Got argument:?'Hello programmer!' Hello programmer! | <sub2 pre=""?0="">< value: Returned info: <sub1></sub1></sub2></sub2></sub2> |
函數sub1調用了三次sub2,三次的參數分別是'Hello world!' ,'Hello earth!' ,'Hello programmer!' ,最后return 0.
???????? 下面初略介紹下上面用到的幾個宏定義:
DBUG_PUSH ("d:t:O");? 設置調試的啟動參數,參數列表在MySQL手冊上也有:
| 標記 | 描述 |
| d | 允許對當前狀態從DBUG_<N>宏輸出??赡芨涣嘘P鍵詞,這些關鍵詞僅對那些帶有? |
| D | 在每個調試起輸出行后延遲。參量一個十分之一秒為單位來延遲的數,它受限于機器的能? |
| f | 限制調試和/或跟蹤,以及簡單設定于列出名字的函數。注意,空列將禁止所用函數。應? |
| F | 對調試或跟蹤輸出的每一行識別源文件名。 |
| i | 對調試或跟蹤輸出的每一行用PID或線程ID識別進程。 |
| g | 允許解析,創建名為的dbugmon.out文件,它包含可用來簡單設定程序的信息??赡芨? |
| L | 為調試或跟蹤輸出的每一行識別源文件行號。 |
| n | 為調試或跟蹤輸出的每一行打印當前函數嵌套深度。 |
| N | 給調試輸出的每一行編號。 |
| o | 重定向調試器輸出流到指定文件。默認輸出是stderr 文件。 |
| O | 類似于 o,但是文件在每次寫操作之間被沖刷。當需要之時,文件在每次寫操作之間被關? |
| p | 限制調試器作用于指定進程。為使調試器動作,一個進程必須用DBUG_PROCESS宏來識? |
| P | 為調試或跟蹤輸出的每一行打印當前進程名字。 |
| r | 當推出一個新狀態時,不繼承前狀態的操作嵌套深度級別。當輸出在左邊空白開始時有? |
| S | 在每個調試過的函數做_sanity(_file_,_line_)函數直到 _sanity() 返回不同于0的結果。(大多? |
| t | 允許函數調用/退出跟蹤行。可能跟著一個給出最大跟蹤級別的數字列(只含一個修改? |
??????? DBUG_PROCESS ("example"); 設置進程名為example
??????? DBUG_ENTER ("sub1"); 表示進入函數sub1
??????? DBUG_PRINT ("info", ("Got argument: '%s'", arg)); 和printf效果差不多,打印出需要的調試信息。
?????? DBUG_RETURN (0);? 在return 0 的基礎上,打印出return 0的調試信息。
三、小結
????? 本文簡單介紹了DBUG的使用方法,沒有深究,源碼很少,卻很實用,在源碼的注釋部分,我看到了是Fred Fish1987年寫的,呃,我才剛出生....,沒想到現在還在看那時候的代碼,可能這就是所謂的經典吧。
?????? 兄弟們,你們還在為復雜環境下的bug調試而苦惱么?還在為堆棧被寫亂掉無從下手而凌亂么?淡定吧,一起來用DBUG吧~~
踏著落葉,追尋著我的夢想。轉載請注明出處總結
以上是生活随笔為你收集整理的MySQL源码学习——DBUG调试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Concurrent包工具类使用
- 下一篇: 常用 SQL 语句汇总