Sun Studio 12: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:

按回车键使光标在屏幕上向下移动(显示屏底部有环绕),按 ^p (Ctrl-p) 使光标向上移动;或者使用向上 (ua) 和向下 (da) 方向键。可使用以下单键命令操作菜单和执行其他任务:

表 8–1 cscope 菜单操作命令

Tab 

移至下一个输入字段。 

回车键 

移至下一个输入字段。 

^n

移至下一个输入字段。 

^p

移至上一个输入字段。 

^y

使用上次键入的文本进行搜索。 

^b

移至上一个输入字段并搜索模式。 

^f

移至下一个输入字段并搜索模式。 

^c

搜索时在不区分/区分大小写之间切换。例如,不区分大小写时,查找 FILE 将找到 fileFile

^r

重新生成交叉引用。 

!

启动交互式 shell。键入 ^d 以返回到 cscope

^l

刷新屏幕。 

显示命令列表。 

^d

退出 cscope

如果您要查找的文本的第一个字符与这些命令之一匹配,您可以通过在该字符之前输入 \(反斜杠)使该命令转义。

现在将光标移至第五个菜单项 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

注 –

按照相同过程执行菜单中列出的除第六项 Change this text string 之外的任何其他任务。由于该任务比其他任务稍微复杂一些,因此要按照另一个过程执行。有关如何更改文本字符串的说明,请参见8.2.8 示例


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

按顺序编辑显示的文件。 

>

将显示的行列表附加至某个文件。 

|

将所有行通过管道传送至某个 shell 命令。 

同样,如果您要查找的文本的第一个字符与这些命令之一匹配,您可以通过在该字符之前输入反斜杠以避免执行命令。

现在,检查新找到的行周围的代码。输入 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() 的函数。

使用标准退出惯例退出编辑器。您即返回至任务菜单。现在,请在第四项 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 查找并列出三个此类函数。

cscope 函数:列出调用 alloctest() 的函数:


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 找到十个此类函数。它会在屏幕上列出其中九个,并指示您按空格键以查看列表的其余部分。

cscope 函数:列出调用 mymalloc() 的函数:


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

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()