メモリ・マップとデバッガ

システム・プログラムI

                                       電子・情報工学系
                                       新城 靖
                                       <yas@is.tsukuba.ac.jp>

このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro1-1998/1998-04-21
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.hlla.is.tsukuba.ac.jp/~yas/index-j.html

■印刷配布資料

■復習

■変数の番地、メモリ・マップ

----------------------------------------------------------------------
   1:	/*
   2:	        vaddr-print.c -- 変数の番地をしらべるプログラム
   3:	        ~yas/syspro1/cc/vaddr-print.c
   4:	        $Header: vaddr-print.c,v 1.1 97/05/19 23:19:10 yas Exp $
   5:	        Start: 1997/05/19 22:58:49
   6:	*/
   7:	#include <stdlib.h>
   8:	
   9:	int x1=1 ;
  10:	int x2 ;
  11:	
  12:	extern int etext, edata, end ;
  13:	
  14:	main( argc,argv,envp )
  15:	    int argc ;
  16:	    char *argv[] ;
  17:	    char *envp[] ;
  18:	{
  19:	    int x3 ;
  20:	    char *x4p ;
  21:	
  22:	        printf("&main == 0x%x \n",&main );
  23:	        printf("&etext == 0x%x \n",&etext );
  24:	        printf("&edata == 0x%x \n",&edata );
  25:	        printf("&end   == 0x%x \n",&end );
  26:	
  27:	        printf("&x1 == 0x%x (data)\n",&x1 );
  28:	        printf("&x2 == 0x%x (bss)\n",&x2 );
  29:	        printf("&x3 == 0x%x (auto)\n",&x3 );
  30:	        x4p = malloc( 10 );
  31:	        printf("x4p == 0x%x (heap)\n",x4p );
  32:	        x4p = malloc( 10 );
  33:	        printf("x4p == 0x%x (heap)\n",x4p );
  34:	        recursive( 3 );
  35:	}
  36:	
  37:	recursive( n )
  38:	    int n ;
  39:	{
  40:	    int x5 ;
  41:	        printf("&x5 == 0x%x (auto,%d)\n",&x5,n );
  42:	        if( n<=0 )
  43:	            return;
  44:	        recursive( n-1 );
  45:	}
----------------------------------------------------------------------

実行例。
----------------------------------------------------------------------
% cp ~yas/syspro1/cc/vaddr-print.c . [←]
% make vaddr-print [←]
cc     vaddr-print.c   -o vaddr-print
% ./vaddr-print [←]
&main == 0x400ad0
&etext == 0x400cb0
&edata == 0x10002000
&end   == 0x10002000
&x1 == 0x100010d0 (data)
&x2 == 0x10001130 (bss)
&x3 == 0x7fff2f1c (auto)
x4p == 0x10002010 (heap)
x4p == 0x10002028 (heap)
&x5 == 0x7fff2ef4 (auto,3)
&x5 == 0x7fff2ecc (auto,2)
&x5 == 0x7fff2ea4 (auto,1)
&x5 == 0x7fff2e7c (auto,0)
% size vaddr-print [←]
text    data    bss     dec     hex     filename
2933    304     28      3265    cc1     vaddr-print
% []
----------------------------------------------------------------------

■デバッガ

◆dbx

使い方。cc に -g オプションを付けてコンパイルする。
% cc -g ファイル名.c -o 実行形式 [←]
% dbx 実行形式 [←]
----------------------------------------------------------------------
% cc -g vaddr-print.c -o vaddr-print
% dbx vaddr-print
dbx version 7.2 Aug 29 1997 03:27:55
Executable /home/lab2/OS/yas/syspro1-1998/cc/vaddr-print
(dbx) list
>*  18  {
    19      int x3 ;
    20      char *x4p ;
    21
    22          printf("&main == 0x%x \n",&main );
    23          printf("&etext == 0x%x \n",&etext );
    24          printf("&edata == 0x%x \n",&edata );
    25          printf("&end   == 0x%x \n",&end );
    26
    27          printf("&x1 == 0x%x (data)\n",&x1 );
(dbx) stop at 27
Process     0: [3] stop at "/home/lab2/OS/yas/syspro1-1998/cc/vaddr-print.c":27
(dbx) run
Process 26330 (vaddr-print) started
&main == 0x400ad0
&etext == 0x400cd0
&edata == 0x10002000
&end   == 0x10002000
[3] Process 26330 (vaddr-print) stopped at [main:27 ,0x400b54]
  27  printf("&x1 == 0x%x (data)\n",&x1 );
(dbx) print x1
1
(dbx) where
>  0 main(argc = 1, argv = 0x7fff2f44, envp = 0x7fff2f4c) ["/home/lab2/OS/yas/sy
spro1-1998/cc/vaddr-print.c":27, 0x400b54]
   1 __istart() ["crt1tinit.s":13, 0x400a90]
(dbx) cont
&x1 == 0x100010d0 (data)
&x2 == 0x10001130 (bss)
&x3 == 0x7fff2f1c (auto)
x4p == 0x10002010 (heap)
x4p == 0x10002028 (heap)
&x5 == 0x7fff2ef4 (auto,3)
&x5 == 0x7fff2ecc (auto,2)
&x5 == 0x7fff2ea4 (auto,1)
&x5 == 0x7fff2e7c (auto,0)
Process 26330 (vaddr-print) terminated
(dbx) quit
%
----------------------------------------------------------------------
良く使うコマンド。
run {引数}
実行
list {行番号}
ソース・プログラムの表示
where
バックトレース
up
関数呼び出しで1つ上(mainに近い方)へ移動
down
関数呼び出しで1つ下(mainに遠い方)へ移動
print 式
表示
next
1行実行。手続き呼び出しがあっても次の行。
step
1行実行。ただし、手続き呼び出しがあると、その手続きの中に入る。
stop at 行番号
その行にブレーク・ポイントの設定
stop in 関数名
その関数にブレーク・ポイントの設定
cont
実行再開。
status
ブレーク・ポイントの表示
delete 番号
ブレーク・ポイントの解除
call 関数(引数)
関数呼び出し。インタプリタ感覚。
func 関数
注目する関数の切り替え
file ファイル名
注目するファイルの切り替え
くわしくは、dbx を実行して help。man dbx。

◆xdbx

X Window のインタフェース。
% xdbx 実行形式 & [←]
% []
残念ながら、SGI では今の所動かない。

◆mule ESC x dbx

Mule の中から dbx を呼ぶ。ソース・プログラム上でどこを実行しているかを 追うことができる。 使い方。
  1. mule を実行する。
  2. ESC x dbx リターン」と打つ。
  3. dbx 実行形式 リターン」と打つ。
dbx のウィンドウでよく使うキー
C-c C-n
next
C-c C-s
step
C-c C-l
ウィンドウを割って、ソースの表示
ソース・プログラムのウィンドウで使えるキー
C-x SPC
ブレーク・ポイントの設定。(現在、残念ながら使えない。誰か修理して欲しい。)

◆gdb

GNU プロジェクトによるデバッガ。 使い方。cc に -g オプションを付けてコンパイルする。
% cc -g ファイル名.c -o 実行形式 [←]
% gdb 実行形式 [←]
注意:今の所、残念ながら、gcc でコンパイルしたものをgdb ではデバッグで きません。

良く使うコマンド。

run {引数}
実行
list {行番号{,行番号}}
ソース・プログラムの表示
bt
バックトレース
print 式
表示
x 式
表示
next
1行実行。手続き呼び出しがあっても次の行。
step
1行実行。ただし、手続き呼び出しがあると、その手続きの中に入る。
b 行番号 (break)
その行にブレーク・ポイントの設定
b 関数名 (break)
その関数にブレーク・ポイントの設定
cont (c)
実行再開。
info b
ブレーク・ポイントの表示
delete 番号
ブレーク・ポイントの解除
call 関数(引数)
関数呼び出し。インタプリタ感覚。
くわしくは、gdb を実行して help。 mule を実行して ESC x info で gdbの項目を見る(まだ入っていない)。

◆xxgdb

X Window のインタフェース。
% xxgdb 実行形式 & [←]
% []
xgdb ではなく、xxgdb。x が2回。

◆mule ESC x gdb

Mule の中から gdb を呼ぶ。ソース・プログラム上でどこを実行しているかを 追うことができる。 使い方。
  1. mule を実行する。
  2. ESC x gdb リターン」と打つ。
  3. gdb 実行形式 リターン」と打つ。
gdb のウィンドウでよく使うキー
C-c C-n
next
C-c C-s
step
C-c C-l
ウィンドウを割って、ソースの表示
ソース・プログラムのウィンドウで使えるキー
C-x SPC
ブレーク・ポイントの設定。(こちらは使える。)

■segmentaton fault(segmentaton violation)


----------------------------------------------------------------------
   1:	/*
   2:	        segv.c -- segmentation violation を起こすプログラム
   3:	        ~yas/syspro1/cc/segv.c
   4:	        $Header$
   5:	        Start: 1998/04/20 23:56:19
   6:	*/
   7:	#include <stdlib.h>
   8:	
   9:	main()
  10:	{
  11:	    char *p ;
  12:	        strcpy(p,"hello");
  13:	        printf("%s\n",p);
  14:	}
----------------------------------------------------------------------

実行例。
----------------------------------------------------------------------
% make segv
cc     segv.c   -o segv
% ./segv
Segmentation fault (core dumped)
% echo $LANG
ja_JP.EUC
% file core
core:           IRIX コア・ダンプ of 'segv'
% ls -l core
-rw-r--r--    1 yas      lab          512   4月 20日 23時58分  core
%  cc -g segv.c -o segv
% dbx segv
dbx version 7.2 Aug 29 1997 03:27:55
core is an incomplete corefile
Executable /home/lab2/OS/yas/syspro1-1998/cc/segv
(dbx) run
Process 26541 (segv) started
Process 26541 (segv) stopped on signal SIGSEGV: Segmentation violation (default)
 at [strcpy:123 ,0xfa6a1c0]
         Source (of strcpy.s) not available for Process 26541
(dbx) where
>  0 strcpy(0xfb68d04, 0x10001000, 0x7fff2f4c, 0x7fff2f4c) ["strcpy.s":123, 0xfa
6a1c0]
   1 main() ["/home/lab2/OS/yas/syspro1-1998/cc/segv.c":12, 0x4009c4]
   2 __istart() ["crt1tinit.s":13, 0x400960]
(dbx) list

         Source (of strcpy.s) not available for Process 26541
(dbx) up
main:  12  strcpy(p,"hello");
(dbx) list
    13          printf("%s\n",p);
    14  }
(dbx) 
----------------------------------------------------------------------

■mainの引数


----------------------------------------------------------------------
   1:   /*
   2:           arg-print.c -- mainの引数を表示するプログラム
   3:           ~yas/syspro1/cc/arg-print.c
   4:           $Header: arg-print.c,v 1.2 97/04/21 18:29:06 yas Exp $
   5:           Start: 1997/04/21 18:23:13
   6:   */
   7:
   8:   main( argc,argv )
   9:       int argc ;
  10:       char *argv[] ;
  11:   {
  12:       int i ;
  13:           printf("argc is %d\n", argc );
  14:           for( i=0 ; i<argc ; i++ )
  15:               printf("argv[%d]: %s\n",i,argv[i] );
  16:   }
----------------------------------------------------------------------

実行例。
----------------------------------------------------------------------
% cp ~yas/syspro1/cc/arg-print.c . [←]
% make arg-print [←]
cc     arg-print.c   -o arg-print
% ./arg-print [←]
argc is 1
argv[0]: ./arg-print
% ./arg-print who am i [←]
argc is 4
argv[0]: ./arg-print
argv[1]: who
argv[2]: am
argv[3]: i
% []
----------------------------------------------------------------------

★練習問題

★練習問題8 printfの番地

printf 関数の番地を調べなさい。

★練習問題9 引数の番地

関数の引数の番地を調べなさい。auto変数と比較しなさい。

★練習問題10 デバッガ

cc -g で作ったプログラムを、dbx または gdb を使って実行しなさい。デバッ ガのコマンド実行してみなさい。

★練習問題11 Segmentation fault

Segmentation fault を起こすプログラムをかきなさい。 それをデバッガで追跡して、どこで起きたかを調べてなさい。
↑[もどる] ←[4月21日] ・[4月21日] →[4月28日]
Last updated: 1998/05/26 10:42:25
Yasushi Shinjo / <yas@is.tsukuba.ac.jp>