色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Linux下C應(yīng)用程序開發(fā)

          Linux下C應(yīng)用程序開發(fā)

          作者: 時(shí)間:2011-05-20 來源:網(wǎng)絡(luò) 收藏
          gdb 舉例
            本節(jié)用一個(gè)實(shí)例教你一步步的用 gdb 調(diào)試程序. 被調(diào)試的程序相當(dāng)?shù)暮唵? 但它展示了 gdb 的典型.
            下面列出了將被調(diào)試的程序. 這個(gè)程序被稱為 hello , 它顯示一個(gè)簡單的問候, 再用反序?qū)⑺谐?
            #include stdio.h>;
            static void my_print (char *);
            static void my_print2 (char *);
            main ()
            {
            char my_string[] = hello world!;
            my_print (my_string);
            my_print2 (my_string);
            }
            void my_print (char *string)
            {
            printf (The string is %s , string);
            }
            void my_print2 (char *string)
            {
            char *string2;
            int size, i;
            size = strlen (string);
            string2 = (char *) malloc (size + 1);
            for (i = 0; i size; i++)
            string2[size - i] = string;
            string2[size+1] = '';
            printf (The string printed backward is %s , string2);
            }
            用下面的命令編譯它:
            gcc -g -o hello hello.c
            這個(gè)程序執(zhí)行時(shí)顯示如下結(jié)果:
            ../hello
            The string is hello world!
            The string printed backward is
            輸出的第一行是正確的, 但第二行打印出的東西并不是我們所期望的. 我們所設(shè)想的輸出
            應(yīng)該是:
            The string printed backward is !dlrow olleh
            由于某些原因, my_print2 函數(shù)沒有正常工作. 讓我們用 gdb 看看問題究竟出在哪兒,
            先鍵入如下命令:
            gdb hello
          ------------------------------------------------------------------------------
          --
          注意: 記得在編譯 hello 程序時(shí)把調(diào)試選項(xiàng)打開.
          ------------------------------------------------------------------------------
          --
            如果你在輸入命令時(shí)忘了把要調(diào)試的程序作為參數(shù)傳給 gdb , 你可以在 gdb 提示符下用
            file 命令來載入它:
            (gdb) file hello
            這個(gè)命令將載入 hello 可執(zhí)行文件就象你在 gdb 命令行里裝入它一樣.
            這時(shí)你能用 gdb 的 run 命令來運(yùn)行 hello 了. 當(dāng)它在 gdb 里被運(yùn)行后結(jié)果大約會(huì)象這樣:
            (gdb) run
            Starting program: /root/hello
            The string is hello world!
            The string printed backward is
            Program exited with code 040
            這個(gè)輸出和在 gdb 外面運(yùn)行的結(jié)果一樣. 問題是, 為什么反序打印沒有工作? 為了找出癥結(jié)所在, 我們可以在 my_print2 函數(shù)的 for 語句后設(shè)一個(gè)斷點(diǎn), 具體的做法是在 gdb
          提示符下鍵入 list 命令三次, 列出源代碼:
            (gdb) list
            (gdb) list
            (gdb) list
          ------------------------------------------------------------------------------
          --
          技巧: 在 gdb 提示符下按回車健將重復(fù)上一個(gè)命令.
          ------------------------------------------------------------------------------
          --
            第一次鍵入 list 命令的輸出如下:
            1 #include stdio.h>;
            2
            3 static void my_print (char *);
            4 static void my_print2 (char *);
            5
            6 main ()
            7 {
            8 char my_string[] = hello world!;
            9 my_print (my_string);
            10 my_print2 (my_string);
          如果按下回車, gdb 將再執(zhí)行一次 list 命令, 給出下列輸出:
            11 }
            12
            13 void my_print (char *string)
            14 {
            15 printf (The string is %s , string);
            16 }
            17
            18 void my_print2 (char *string)
            19 {
            20 char *string2;
            再按一次回車將列出 hello 程序的剩余部分:
            21 int size, i;
            22
            23 size = strlen (string);
            24 string2 = (char *) malloc (size + 1);
            25 for (i = 0; i size; i++)
            26 string2[size - i] = string;
            27 string2[size+1] = '';
            28
            29 printf (The string printed backward is %s , string2);
            30 }
            根據(jù)列出的源程序, 你能看到要設(shè)斷點(diǎn)的地方在第26行, 在 gdb 命令行提示符下鍵入如下命令設(shè)置斷點(diǎn):
            (gdb) break 26
            gdb 將作出如下的響應(yīng):
            Breakpoint 1 at 0x804857c: file hello.c, line 26.
            (gdb)
            現(xiàn)在再鍵入 run 命令, 將產(chǎn)生如下的輸出:
            Starting program: /root/hello
            The string is hello world!
            Breakpoint 1, my_print2 (string=0xbffffab0 hello world!) at hello.c:26
            26 string2[size - i] = string;
            你能通過設(shè)置一個(gè)觀察 string2[size - i] 變量的值的觀察點(diǎn)來看出錯(cuò)誤是怎樣產(chǎn)生的,
            做法是鍵入:
            (gdb) watch string2[size - i]
            gdb 將作出如下回應(yīng):
            Hardware watchpoint 2: string2[size - i]
            現(xiàn)在可以用 next 命令來一步步的執(zhí)行 for 循環(huán)了:
            (gdb) next
            經(jīng)過第一次循環(huán)后, gdb 告訴我們 string2[size - i] 的值是 `h`. gdb 用如下的顯示來告訴你這個(gè)信息:
            Hardware watchpoint 2: string2[size - i]
            Old value = 0 '00'
            New value = 104 'h'
            my_print2 (string=0xbffffab0 hello world!) at hello.c:25
            25 for (i = 0; i size; i++)
            這個(gè)值正是期望的. 后來的數(shù)次循環(huán)的結(jié)果都是正確的. 當(dāng) i=11 時(shí), 表達(dá)式
            string2[size - i] 的值等于 `!`, size - i 的值等于 1, 最后一個(gè)字符已經(jīng)拷到新串里了.
            如果你再把循環(huán)執(zhí)行下去, 你會(huì)看到已經(jīng)沒有值分配給 string2[0] 了, 而它是新串的第一個(gè)字符, 因?yàn)?malloc 函數(shù)在分配內(nèi)存時(shí)把它們初始化為空(null)字符. 所以 string2 的第一個(gè)字符是空字符. 這解釋了為什么在打印 string2 時(shí)沒有任何輸出了.
            現(xiàn)在找出了問題出在哪里, 修正這個(gè)錯(cuò)誤是很容易的. 你得把代碼里寫入 string2 的第一個(gè)字符的的偏移量改為 size - 1 而不是 size. 這是因?yàn)?string2 的大小為 12, 但起始偏移量是 0, 串內(nèi)的字符從偏移量 0 到 偏移量 10, 偏移量 11 為空字符保留.
            改正方法非常簡單. 這是這種解決辦法的代碼:
            #include stdio.h>;
            static void my_print (char *);
            static void my_print2 (char *);
            main ()
            {
            char my_string[] = hello world!;
            my_print (my_string);
            my_print2 (my_string);
            }
            void my_print (char *string)
            {
            printf (The string is %s , string);
            }
            void my_print2 (char *string)
            {
            char *string2;
            int size, i;
            size = strlen (string);
            string2 = (char *) malloc (size + 1);
            for (i = 0; i size; i++)
            string2[size -1 - i] = string;
            string2[size] = '';
            printf (The string printed backward is %s , string2);
            }
            如果程序產(chǎn)生了core文件,可以用gdb hello core命令來查看程序在何處出錯(cuò)。如在函數(shù)my_print2()中,如果忘記了給string2分配內(nèi)存 string2 = (char *) malloc (size + 1);,很可能就會(huì)  core dump. linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          linux相關(guān)文章:linux教程




          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉