1. 程式人生 > >linux下實現簡易shell

linux下實現簡易shell

基本命令 copyright 本地 code ats 準備 () bject 能夠

GDB是GNU項目調試器,支持C、C++、Go、Fortran、Object-C、Assembly等。能夠暫停程序運行,調試程序(包括本地調試、遠程調試),如何遠程調試我將在之後的文章中寫道,本篇只討論基本用法。

首先準備gdb調試環境:-g參數

$ gcc -g *.c
$ ls
a.out a.out.dSYM

-g參數讓編譯器在生成可執行文件a.out時加入調試信息(在a.out.dSYM目錄下)

啟動gdb

$ gdb a.out
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 Free Software Foundation, Inc.
...
(gdb)

現在我們進入了gdb的調試界面

熟悉幾個基本命令:

  • l 列出附近10行代
  • b [n] 設置斷點在第幾行(也可寫函數名)
  • r 開始調試
  • n 執行下一行
  • c 執行到下一斷點
  • q 退出gdb
  • p [argv] 打印參數
  • s 進入函數
  • watch [v] 觀察變量變化

下面有一段程序

main.c

 1 #include <stdio.h>
 2 #include "func.h"
 3 
 4 int main()
 5 {
 6     char str[] = "This is a test."; // line 6
 7     int len = myStrlen(str);
8 printf("len:%d\n", len); 9 10 return 0; 11 }

func.c

 1 int myStrlen(const char *str)
 2 {
 3     int len = 0;
 4     const char *p = str;
 5     while (*p != \0) {
 6         ++len;
 7         ++p;
 8     }
 9     return len;
10 }

在main.c第6行設置斷點(想在main.c中給func.c設置斷點輸入b func.c:3

(gdb) b 6
Breakpoint 1 at 0x100000f11: file main.c, line 6.

開始調試,程序自動暫停在第6行(此行即將執行,str尚未賦值)

(gdb) r
Starting program: /Users/mgrwang/Dev/test/a.out

Breakpoint 1, main () at main.c:6
6    char str[] = "This is a test.";
(gdb) p str
$1 = \000 <repeats 15 times>

向下執行,程序運行到第7行

(gdb) n    
7    int len = myStrlen(str);
(gdb) p str
$3 = "This is a test."

輸入s進入函數體myStrlen,如果想繼續執行不查看函數,輸入n執行下一行

(gdb) s
myStrlen (str=0x7fff5fbff980 "This is a test.") at func.c:3
3    int len = 0;

查看程序執行位置附近代碼

(gdb) l
1    int myStrlen(const char *str)
2    {
3      int len = 0;
4      const char *p = str;
5      while (*p != \0) {
6        ++len;
7        ++p;
8      }
9      return len;
10   }

(省略部分執行細節)

觀察變量p值變化

(gdb) watch *p
Hardware watchpoint 3: *p

Old value = 84 T
New value = 104 h

退出調試

(gdb) watch *p
Hardware watchpoint 3: *p

Old value = 84 T
New value = 104 h

linux下實現簡易shell