DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 
C programmer's productivity tools

A tutorial example: locating the source of the error message

In this example, the task is to locate the source of an error message ``out of storage'' that is printed when a program is run. Assume that you are working with unfamiliar code. You will invoke cscope and start your search for the problem by locating the section of code where the error message is generated. Move the cursor to the fifth menu item, that is:

List lines containing this text string

Now enter the text to be searched for:

out of storage

This process is shown in the next example.

   cscope 		Press the ? key for help
   

List references to this C symbol: Edit this function or #define: List functions called by this function: List functions calling this function: List lines containing this text string: out of storage Change this text string: List file names containing this text string:

Press the <Return> key. The cscope tool searches for the specified text and finds one line that contains it.


NOTE: The same procedure is followed to perform any other task listed in the menu, except the sixth, changing a text string. For a description and examples of changing a text string, see ``Changing a text string''.

cscope reports its findings as follows:

   Text string: out of storage
   

File Line 1 alloc.c 56 (void) fprintf(stderr, "\n%s: out of storage\n", argv[0] );

Edit this function or #define: List functions called by this function: List functions calling this function: List lines containing this text string: Change this text string: List file names containing this text string:

After cscope shows the results of a successful search in this way, you have several options. For example, you may want to edit one of the lines found. If cscope has found several lines and a list of them will not fit on the screen at once, you may want to look at the next part of the list. The following table shows the commands available after cscope has found the specified text.

Commands for use after initial search

Command Meaning
1-9 edit this line
  (the number you type corresponds to an item
  in the list of lines printed by cscope)
space display the lines after the current line
+ display the lines after the current line
- display the lines before the current line
<Ctrl>e edit all lines
> append the list of lines being displayed to a file


NOTE: If the first character of the text you are searching for matches one of these commands, precede it with a ``\'' (backslash).

Now examine the code around the newly found line. Enter ``1'' (the number of the line in the list). The editor will be invoked with the file alloc.c; the cursor will be at the beginning of line 56 of the text file.

   {
       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", argv[0]); exit(C); } return(p); } ~ ~ ~ ~ ~ ~ ~ "alloc.c" 60 lines, 1022 characters

By examining the code, you learn that the error message is generated when the variable p is NULL. To determine how an argument passed to alloctest could have been NULL, you must first identify the functions that call alloctest.

Exit the editor by using normal write and quit conventions, and return to the menu of tasks. Now request a list of functions that call alloctest, as shown in the next example:

   Text string: out of storage
   

File Line 1 alloc.c 56 (void) fprintf(stderr, "\n%s: out of storage\n", argv[0] );

List references to this C symbol: Edit this function or #define: List functions called by this function: List functions calling this function: alloctest List lines containing this text string: Change this text string: List file names containing this text string:

cscope finds and lists three such functions:
   Functions calling this function: alloctest
   

File Function Line 1 alloc.c mymalloc 26 return(alloctest(malloc((unsigned) size))); 2 alloc.c mycalloc 36 return(alloctest(calloc((unsigned) nelem, (unsigned) size))); 3 alloc.c myrealloc 46 return(alloctest(realloc(p, (unsigned) size)));

List references to this C symbol: Edit this function or #define: List functions called by this function: List functions calling this function: List lines containing this text string: Change this text string: List file names containing this text string:

Now you need to know which functions call mymalloc. cscope finds ten such functions. It lists seven of them on the screen and instructs you to press the space bar to see the rest of the list.
   Functions calling this function: mymalloc
   

File Function Line 1 alloc.c stralloc 17 return(strcpy(mymalloc(strlen(s) + 1), s)); 2 dir.c makesrcdirlist 70 srcdirs = (char **) mymalloc(nsrcdirs*sizeof(char*)); 3 dir.c makesrcdirlist 89 s = mymalloc(strlen(srcdirs[i]) + n); 4 dir.c makefilelist 115 srcfiles = (char **) mymalloc(msrcfiles*sizeof(char*)); 5 dir.c makefilelist 116 srcnames = (char **) mymalloc(msrcfiles*sizeof(char*)); 6 dir.c addincdir 212 incdirs = (char **) mymalloc(sizeof(char *)); 7 display.c dispinit 76 displine = (int *) mymalloc(mdisprefs * sizeof(int));

* 3 more lines - press the space bar to display more * List references to this C symbol: Edit this function or #define: List functions called by this function: List functions calling this function: List lines containing this text string: Change this text string: List file names containing this text string:

Because you know that the error message ("out of storage") is generated at the beginning of the program, you can guess that the problem may have occurred in the function dispinit (display initialization). To view dispinit, the seventh function on the list, type ``7'':
   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" 440 lines, 10198 characters

Examining this code, you will see that mymalloc failed because it was called with a negative number. You are now in a position to fix the problem. The program needs a mechanism such that if the value of the variable mdisprefs is negative, it will abort after printing a meaningful error message.

Stacking cscope and editor calls

cscope and editor calls can be stacked. This means that when cscope puts you in the editor to display one symbol reference and there is another symbol of interest, you can call cscope again from within the editor without exiting the current invocation of either cscope or the editor. You can then back up to a previous invocation by exiting the appropriate cscope and editor calls.


Next topic: Conditional compilation directives
Previous topic: The cross-reference file

© 2003 Caldera International, Inc. All rights reserved.
SCO OpenServer Release 5.0.7 -- 11 February 2003