Oracle Solaris Studio 12.2: C ユーザーガイド

8.2.3 ステップ 3: コード位置の確定

本節の最初で述べた本来の作業に戻り、「out of storage」のエラーメッセージの原因となっている場所を確定します。cscope が起動され、相互参照表が作成されました。画面には、cscope の作業メニューが表示されます。

cscope の作業メニュー


% cscope

cscope     Press the ? key for help


Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

Return キーを押すと、カーソルが下に移動し (画面の一番下まで移動すると、先頭に戻る)、^p (Ctrl+p キー) を押すと、上に移動します。また、上矢印 (ua) と下矢印 (da) キーも使用できます。次の単一キーコマンドを使用すれば、メニュー操作とそのほかの作業が行えます。

表 8–1 cscope メニュー操作コマンド

Tab 

次の入力フィールドへ移動する 

Return 

次の入力フィールドへ移動する 

^n

次の入力フィールドへ移動する 

^p

前の入力フィールドへ移動する 

^y

最後に入力したテキストを検索する 

^b

逆方向にパターンを検索する 

^f

順方向にパターンを検索する 

^c

検索時に大文字と小文字を区別するか否かのトグルスイッチ (大文字と小文字を区別しない場合、たとえば FILE 文字列は fileFile の両方と一致)。

^r

相互参照表を再作成する 

!

対話型シェルを起動する (^dcscope に復帰)

^l

画面を描き直す 

?

コマンドのリストを表示する 

^d

cscope を終了する

検索文字列の最初の文字が前述のいずれかのコマンドと一致する場合は、検索文字列の前にバックスラッシュ (\) を加えてコマンドと区別します。

たとえば、カーソルを 5 番目のメニュー項目「Find this text string」に移動して文字列「out of storage」を入力し、Return キーを押します。

cscope 関数: 文字列検索の要求


$ cscope

cscope     Press the ? key for help


Find this C symbol
Find this global definition
Find functions called by this function
Find functions calling this function
Find this text string:  out of storage
Change this text string
Find this egrep pattern
Find this file
Find files #including this file

注 –

6 番目の「Change this text string」項目以外のメニュー項目についても同じ手順に従ってください。6 番目の項目はほかの項目よりも多少複雑なので手順が異なります。文字列の変更方法については、「8.2.8 例」を参照してください。


cscope は指定された文字列を検索し、それを含む行を見つけ出して次のように検索結果を表示します。

cscope 関数: 文字列を含む cscope 行のリスト表示


Text string: out of storage

  File Line
1 alloc.c 63 (void) fprintf(stderr, "\n%s:  out of storage\n", argv0);


Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

cscope によって検索結果が正常に表示されたら、次の操作を選択します。行を変更したり、またはその行の前後をエディタで調べることができます。あるいは、cscope の検索結果のリストが一画面に収まらない場合は、リストの次の部分を見ることもできます。cscope が指定した文字列を検索したあとに使用可能なコマンドを次に示します。

表 8–2 最初の検索後に使用するコマンド

1 -9

この行を含むファイルを編集する (入力した番号は cscope が表示したリストの行番号に対応する)

スペース 

次画面のリストを表示する 

+

次画面のリストを表示する 

^v

次画面のリストを表示する 

前画面のリストを表示する 

^e

表示されたファイル順に編集する 

>

表示されているリストをファイルへ追加する 

|

全行をパイプでシェルコマンドに渡す 

ここでも、検索文字列の最初の文字が前述のいずれかのコマンドと一致する場合は、検索文字列の前にバックスラッシュ (\) を加えてコマンドと区別します。

次に、新しく検索した行の前後を調べます。「1」 (リスト内の行番号) を入力してください。エディタが起動され、alloc.c ファイルが読み込まれます。カーソルは、alloc.c の 63 行目の先頭に移動します。

cscope 関数: コード行の検査


{
   return(alloctest(realloc(p, (unsigned) size)));
}

/* check for memory allocation failure */

static char *
alloctest(p)
char *p;
{
    if (p == NULL) {
        (void) fprintf(stderr, "\n%s:  out of storage\n", argv0);
        exit(1);
    }
    return(p);
}
~
~
~
~
~
~
~
"alloc.c" 67 lines, 1283 characters

変数 pNULL のときに、エラーメッセージが出力されることがわかります。alloctest() に渡される引数がなぜ NULL になったのかを調べるには、まず alloctest() を呼び出している関数を確定する必要があります。

通常の終了方法でエディタを終了し、作業メニューに戻ります。ここで、4 番目の項目「Find functions calling this function」のあとに alloctest と入力します。

cscope 関数: alloctest() を呼び出す関数のリストの要求


Text string: out of storage

  File Line
1 alloc.c 63(void)fprintf(stderr,"\n%s:  out of storage\n",argv0);


Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:  alloctest
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

cscope は検索を実行し、次の 3 つの関数のリストを表示します。

cscope 関数: alloctest() を呼び出す Listing 関数


Functions calling this function: alloctest
File Function Line
1 alloc.c mymalloc 33 return(alloctest(malloc((unsigned) size)));
2 alloc.c mycalloc 43 return(alloctest(calloc((unsigned) nelem, (unsigned) size)));
3 alloc.c myrealloc 53 return(alloctest(realloc(p, (unsigned) size)));


Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

今度は、mymalloc() を呼び出す関数を調べます。cscope は、次のような 10 個の関数を見つけ出します。そのうち 9 個を画面に表示し、残りの 1 個を見るにはスペースバーを押すように指示しています。

cscope 関数: mymalloc() を呼び出す Listing 関数


Functions calling this function: mymalloc

File         Function       Line
1 alloc.c    stralloc       24 return(strcpy(mymalloc
                            (strlen(s) + 1), s));
2 crossref.c crossref       47 symbol = (struct symbol *)mymalloc
                            (msymbols * sizeof(struct symbol));
3 dir.c      makevpsrcdirs  63 srcdirs = (char **) mymalloc
                            (nsrcdirs * sizeof(char*));
4 dir.c      addincdir      167 incdirs = (char **)mymalloc
                            (sizeof(char *));
5 dir.c      addincdir      168 incnames = (char **)
                            mymalloc(sizeof(char *));
6 dir.c      addsrcfile     439 p = (struct listitem *) mymalloc
                            (sizeof(struct listitem));
7 display.c  dispinit       87 displine = (int *) mymalloc
                            (mdisprefs * sizeof(int));
8 history.c  addcmd         19  h = (struct cmd *) mymalloc
                            (sizeof(struct cmd));
9 main.c     main           212 s = mymalloc((unsigned )
                            (strlen(reffile) +strlen(home) + 2));

* 9 more lines - press the space bar to display more *
Find this C symbol:
Find this global definition:
Find functions called by this function:
Find functions calling this function:
Find this text string:
Change this text string:
Find this egrep pattern:
Find this file:
Find files #including this file:

「out of storage」のエラーメッセージはプログラムの開始直後に出力されるので、関数 dispinit() (表示の初期化) 内で問題が発生していることが推測できます。

dispinit() はリストの 7 番目の関数なので、これを参照するには「7」と入力します。

cscope 関数: dispinit() をエディタで参照


void
dispinit()
{
        /* calculate the maximum displayed reference lines */
    lastdispline = FLDLINE -  4;
    mdisprefs = lastdispline -  REFLINE + 1;
    if (mdisprefs > 9) {
       mdisprefs = 9;
    }
       /* allocate the displayed line array */
   displine = (int *) mymalloc(mdisprefs * sizeof(int));
}
^L/* display a page of the references */

void
display()
{
    char file[PATHLEN + 1]; /* file name */
    char function[PATLEN + 1];/* function name */
    char linenum[NUMLEN + 1]; /* line number */
    int screenline; /* screen line number */
    int width; /* source line display width */
    register int i, j;
"display.c" 622 lines, 14326 characters

mymalloc() が失敗したのは、非常に大きな数または負数を引数にして呼び出されたためです。FLDLINEREFLINE が取り得る値を調べてみると、mdisprefs の値が負になる場合があることがわかります。この場合、mymalloc() は負数を引数にして呼び出されます。