1 /* List lines of source files for GDB, the GNU debugger.
2 Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
4 GDB is distributed in the hope that it will be useful, but WITHOUT ANY
5 WARRANTY. No author or distributor accepts responsibility to anyone
6 for the consequences of using it or for whether it serves any
7 particular purpose or works at all, unless he says so in writing.
8 Refer to the GDB General Public License for full details.
10 Everyone is granted permission to copy, modify and redistribute GDB,
11 but only under the conditions described in the GDB General Public
12 License. A copy of this license is supposed to have been given to you
13 along with GDB so you can know your rights and responsibilities. It
14 should be in a file named COPYING. Among other things, the copyright
15 notice and this notice must be preserved on all copies.
17 In other words, go ahead and share GDB, but don't try to stop
18 anyone else from sharing it farther. Help stamp out software hoarding!
22 #include <sys/param.h>
26 #include "initialize.h"
29 /* Path of directories to search for source files.
30 Same format as the PATH environment variable's value. */
32 static char *source_path
;
34 /* Symtab of default file for listing lines of. */
36 struct symtab
*current_source_symtab
;
38 /* Default next line to list. */
40 int current_source_line
;
42 /* Line number of last line printed. Default for various commands.
43 current_source_line is usually, but not always, the same as this. */
45 static int last_line_listed
;
47 /* First line number listed by last listing command. */
49 static int first_line_listed
;
53 /* Set the source file default for the "list" command,
54 specifying a symtab. */
57 select_source_symtab (s
)
58 register struct symtab
*s
;
62 struct symtab_and_line sal
;
64 /* Make the default place to list be the function `main'
66 if (lookup_symbol ("main", 0, VAR_NAMESPACE
))
68 sal
= decode_line_spec ("main", 1);
69 current_source_symtab
= sal
.symtab
;
70 current_source_line
= sal
.line
- 9;
74 /* If there is no `main', use the last symtab in the list,
75 which is actually the first found in the file's symbol table.
76 But ignore .h files. */
79 char *name
= s
->filename
;
80 int len
= strlen (name
);
81 if (! (len
> 2 && !strcmp (&name
[len
- 2], ".h")))
82 current_source_symtab
= s
;
86 current_source_line
= 1;
93 printf ("Source directories searched: %s\n", source_path
);
99 register struct symtab
*s
;
101 source_path
= savestring (current_directory
, strlen (current_directory
));
103 /* Forget what we learned about line positions in source files;
104 must check again now since files may be found in
105 a different directory now. */
106 for (s
= symtab_list
; s
; s
= s
->next
)
107 if (s
->line_charpos
!= 0)
109 free (s
->line_charpos
);
115 directory_command (dirname
, from_tty
)
119 char *old
= source_path
;
123 if (query ("Reinitialize source path to %s? ", current_directory
))
132 register int len
= strlen (dirname
);
134 extern char *index ();
136 if (index (dirname
, ':'))
137 error ("Please add one directory at a time to the source path.");
138 if (dirname
[len
- 1] == '/')
139 /* Sigh. "foo/" => "foo" */
140 dirname
[--len
] == '\0';
142 while (dirname
[len
- 1] == '.')
146 /* "." => getwd () */
147 dirname
= current_directory
;
150 else if (dirname
[len
- 2] == '/')
155 dirname
[--len
] = '\0';
160 /* "...foo/." => "...foo" */
161 dirname
[len
-= 2] = '\0';
168 if (dirname
[0] != '/')
169 dirname
= concat (current_directory
, "/", dirname
);
171 dirname
= savestring (dirname
, len
);
172 make_cleanup (free
, dirname
);
174 if (stat (dirname
, &st
) < 0)
175 perror_with_name (dirname
);
176 if ((st
.st_mode
& S_IFMT
) != S_IFDIR
)
177 error ("%s is not a directory.", dirname
);
180 len
= strlen (dirname
);
184 if (!strncmp (tem
, dirname
, len
)
185 && (tem
[len
] == '\0' || tem
[len
] == ':'))
187 printf ("\"%s\" is already in the source path.\n",
191 tem
= index (tem
, ':');
196 source_path
= concat (old
, ":", dirname
);
206 /* Open a file named STRING, searching path PATH (dir names sep by colons)
207 using mode MODE and protection bits PROT in the calls to open.
208 If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
209 (ie pretend the first element of PATH is ".")
210 If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
211 the actual file opened (this string will always start with a "/"
213 If a file is found, return the descriptor.
214 Otherwise, return -1, with errno set for the last name we tried to open. */
216 /* >>>> This should only allow files of certain types,
217 >>>> eg executable, non-directory */
219 openp (path
, try_cwd_first
, string
, mode
, prot
, filename_opened
)
225 char **filename_opened
;
228 register char *filename
;
229 register char *p
, *p1
;
233 while (string
[0] == '.' && string
[1] == '/')
236 if (try_cwd_first
|| string
[0] == '/')
239 fd
= open (filename
, mode
, prot
);
240 if (fd
>= 0 || string
[0] == '/')
244 filename
= (char *) alloca (strlen (path
) + strlen (string
) + 2);
246 for (p
= path
; p
; p
= p1
? p1
+ 1 : 0)
248 p1
= (char *) index (p
, ':');
254 strncpy (filename
, p
, len
);
256 strcat (filename
, "/");
257 strcat (filename
, string
);
259 fd
= open (filename
, mode
, prot
);
266 *filename_opened
= (char *) 0;
267 else if (filename
[0] == '/')
268 *filename_opened
= savestring (filename
, strlen (filename
));
271 *filename_opened
= concat (current_directory
, "/", filename
);
277 /* Create and initialize the table S->line_charpos that records
278 the positions of the lines in the source file, which is assumed
279 to be open on descriptor DESC.
280 All set S->nlines to the number of such lines. */
283 find_source_lines (s
, desc
)
288 register char *data
, *p
, *end
;
290 int lines_allocated
= 1000;
291 int *line_charpos
= (int *) xmalloc (lines_allocated
* sizeof (int));
292 extern int exec_mtime
;
295 if (get_exec_file (0) != 0 && exec_mtime
< st
.st_mtime
)
296 printf ("Source file is more recent than executable.\n");
298 data
= (char *) alloca (st
.st_size
);
299 myread (desc
, data
, st
.st_size
);
300 end
= data
+ st
.st_size
;
307 /* A newline at the end does not start a new line. */
310 if (nlines
== lines_allocated
)
312 lines_allocated
*= 2;
313 line_charpos
= (int *) xrealloc (line_charpos
,
314 sizeof (int) * lines_allocated
);
316 line_charpos
[nlines
++] = p
- data
;
320 s
->line_charpos
= (int *) xrealloc (line_charpos
, nlines
* sizeof (int));
323 /* Return the character position of a line LINE in symtab S.
324 Return 0 if anything is invalid. */
327 source_line_charpos (s
, line
)
332 if (!s
->line_charpos
|| line
<= 0) return 0;
333 if (line
> s
->nlines
)
335 return s
->line_charpos
[line
- 1];
338 /* Return the line number of character position POS in symtab S. */
341 source_charpos_line (s
, chr
)
342 register struct symtab
*s
;
345 register int line
= 0;
348 if (s
== 0 || s
->line_charpos
== 0) return 0;
349 lnp
= s
->line_charpos
;
350 /* Files are usually short, so sequential search is Ok */
351 while (line
< s
->nlines
&& *lnp
<= chr
)
356 if (line
>= s
->nlines
)
361 /* Get full pathname and line number positions for a symtab.
362 Return nonzero if line numbers may have changed.
363 Set *FULLNAME to actual name of the file as found by `openp',
364 or to 0 if the file is not found. */
367 get_filename_and_charpos (s
, line
, fullname
)
372 register int desc
, linenums_changed
= 0;
374 desc
= openp (source_path
, 0, s
->filename
, O_RDONLY
, 0, &s
->fullname
);
382 *fullname
= s
->fullname
;
383 if (s
->line_charpos
== 0) linenums_changed
= 1;
384 if (linenums_changed
) find_source_lines (s
, desc
);
386 return linenums_changed
;
389 /* Print text describing the full name of the source file S
390 and the line number LINE and its corresponding character position.
391 The text starts with two Ctrl-z so that the Emacs-GDB interface
394 MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
396 Return 1 if successful, 0 if could not find the file. */
399 identify_source_line (s
, line
, mid_statement
)
404 if (s
->line_charpos
== 0)
405 get_filename_and_charpos (s
, line
, 0);
406 if (s
->fullname
== 0)
408 printf ("\032\032%s:%d:%d:%s\n", s
->fullname
,
409 line
, s
->line_charpos
[line
- 1],
410 mid_statement
? "middle" : "beg");
411 current_source_line
= line
;
412 first_line_listed
= line
;
413 last_line_listed
= line
;
414 current_source_symtab
= s
;
418 /* Print source lines from the file of symtab S,
419 starting with line number LINE and stopping before line number STOPLINE. */
422 print_source_lines (s
, line
, stopline
, noerror
)
429 register FILE *stream
;
430 int nlines
= stopline
- line
;
432 desc
= openp (source_path
, 0, s
->filename
, O_RDONLY
, 0, &s
->fullname
);
437 perror_with_name (s
->filename
);
438 print_sys_errmsg (s
->filename
, errno
);
442 if (s
->line_charpos
== 0)
443 find_source_lines (s
, desc
);
445 if (line
< 1 || line
> s
->nlines
)
448 error ("Line number out of range; %s has %d lines.",
449 s
->filename
, s
->nlines
);
452 if (lseek (desc
, s
->line_charpos
[line
- 1], 0) < 0)
455 perror_with_name (s
->filename
);
458 current_source_symtab
= s
;
459 current_source_line
= line
;
460 first_line_listed
= line
;
462 stream
= fdopen (desc
, "r");
469 last_line_listed
= current_source_line
;
470 printf ("%d\t", current_source_line
++);
473 if (c
< 040 && c
!= '\t' && c
!= '\n')
476 fputc (c
+ 0100, stdout
);
482 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
489 list_command (arg
, from_tty
)
493 struct symtab_and_line sal
, sal_end
;
502 if (symtab_list
== 0)
503 error ("Listing source lines requires symbols.");
505 /* "l" or "l +" lists next ten lines. */
507 if (arg
== 0 || !strcmp (arg
, "+"))
509 if (current_source_symtab
== 0)
510 error ("No default source file yet. Do \"help list\".");
511 print_source_lines (current_source_symtab
, current_source_line
,
512 current_source_line
+ 10, 0);
516 /* "l -" lists previous ten lines, the ones before the ten just listed. */
517 if (!strcmp (arg
, "-"))
519 if (current_source_symtab
== 0)
520 error ("No default source file yet. Do \"help list\".");
521 print_source_lines (current_source_symtab
,
522 max (first_line_listed
- 10, 1),
523 first_line_listed
, 0);
527 /* Now if there is only one argument, decode it in SAL
529 If there are two arguments, decode them in SAL and SAL_END
530 and clear NO_END; however, if one of the arguments is blank,
531 set DUMMY_BEG or DUMMY_END to record that fact. */
537 sal
= decode_line_1 (&arg1
, 0, 0, 0);
539 /* Record whether the BEG arg is all digits. */
541 for (p
= arg
; p
!= arg1
&& *p
>= '0' && *p
<= '9'; p
++);
542 linenum_beg
= (p
== arg1
);
544 while (*arg1
== ' ' || *arg1
== '\t')
550 while (*arg1
== ' ' || *arg1
== '\t')
555 sal_end
= decode_line_1 (&arg1
, 0, 0, 0);
557 sal_end
= decode_line_1 (&arg1
, 0, sal
.symtab
, sal
.line
);
561 error ("Junk at end of line specification.");
563 if (!no_end
&& !dummy_beg
&& !dummy_end
564 && sal
.symtab
!= sal_end
.symtab
)
565 error ("Specified start and end are in different files.");
566 if (dummy_beg
&& dummy_end
)
567 error ("Two empty args do not say what lines to list.");
569 /* if line was specified by address,
570 first print exactly which line, and which file.
571 In this case, sal.symtab == 0 means address is outside
572 of all known source files, not that user failed to give a filename. */
576 error ("No source file for address 0x%x.", sal
.pc
);
577 sym
= find_pc_function (sal
.pc
);
579 printf ("0x%x is in %s (%s, line %d).\n",
580 sal
.pc
, SYMBOL_NAME (sym
), sal
.symtab
->filename
, sal
.line
);
582 printf ("0x%x is in %s, line %d.\n",
583 sal
.pc
, sal
.symtab
->filename
, sal
.line
);
586 /* If line was not specified by just a line number,
587 and it does not imply a symtab, it must be an undebuggable symbol
588 which means no source code. */
590 if (! linenum_beg
&& sal
.symtab
== 0)
591 error ("No line number known for %s.", arg
);
593 /* If this command is repeated with RET,
594 turn it into the no-arg variant. */
599 if (dummy_beg
&& sal_end
.symtab
== 0)
600 error ("No default source file yet. Do \"help list\".");
602 print_source_lines (sal_end
.symtab
, max (sal_end
.line
- 9, 1),
603 sal_end
.line
+ 1, 0);
604 else if (sal
.symtab
== 0)
605 error ("No default source file yet. Do \"help list\".");
607 print_source_lines (sal
.symtab
, max (sal
.line
- 5, 1), sal
.line
+ 5, 0);
609 print_source_lines (sal
.symtab
, sal
.line
,
610 dummy_end
? sal
.line
+ 10 : sal_end
.line
+ 1,
614 /* Print info on range of pc's in a specified line. */
617 line_info (arg
, from_tty
)
621 struct symtab_and_line sal
;
622 int start_pc
, end_pc
;
626 sal
.symtab
= current_source_symtab
;
627 sal
.line
= last_line_listed
;
631 sal
= decode_line_spec (arg
, 0);
633 /* If this command is repeated with RET,
634 turn it into the no-arg variant. */
641 error ("No source file specified.");
643 && find_line_pc_range (sal
.symtab
, sal
.line
, &start_pc
, &end_pc
))
645 if (start_pc
== end_pc
)
646 printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
647 sal
.line
, sal
.symtab
->filename
, start_pc
);
649 printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
650 sal
.line
, sal
.symtab
->filename
, start_pc
, end_pc
);
651 /* x/i should display this line's code. */
652 set_next_address (start_pc
);
653 /* Repeating "info line" should do the following line. */
654 last_line_listed
= sal
.line
+ 1;
657 printf ("Line number %d is out of range for \"%s\".\n",
658 sal
.line
, sal
.symtab
->filename
);
661 /* Commands to search the source file for a regexp. */
664 forward_search_command (regex
, from_tty
)
669 register FILE *stream
;
670 int line
= last_line_listed
+ 1;
673 msg
= (char *) re_comp (regex
);
677 if (current_source_symtab
== 0)
678 error ("No default source file yet. Do \"help list\".");
680 /* Search from last_line_listed+1 in current_source_symtab */
682 desc
= openp (source_path
, 0, current_source_symtab
->filename
,
683 O_RDONLY
, 0, ¤t_source_symtab
->fullname
);
685 perror_with_name (current_source_symtab
->filename
);
687 if (current_source_symtab
->line_charpos
== 0)
688 find_source_lines (current_source_symtab
, desc
);
690 if (line
< 1 || line
> current_source_symtab
->nlines
)
693 error ("Expression not found");
696 if (lseek (desc
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
699 perror_with_name (current_source_symtab
->filename
);
702 stream
= fdopen (desc
, "r");
705 char buf
[4096]; /* Should be reasonable??? */
706 register char *p
= buf
;
713 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
715 /* we now have a source line in buf, null terminate and match */
717 if (re_exec (buf
) > 0)
721 print_source_lines (current_source_symtab
,
723 current_source_line
= max (line
- 5, 1);
729 printf ("Expression not found\n");
734 reverse_search_command (regex
, from_tty
)
739 register FILE *stream
;
740 int line
= last_line_listed
- 1;
743 msg
= (char *) re_comp (regex
);
747 if (current_source_symtab
== 0)
748 error ("No default source file yet. Do \"help list\".");
750 /* Search from last_line_listed-1 in current_source_symtab */
752 desc
= openp (source_path
, 0, current_source_symtab
->filename
,
753 O_RDONLY
, 0, ¤t_source_symtab
->fullname
);
755 perror_with_name (current_source_symtab
->filename
);
757 if (current_source_symtab
->line_charpos
== 0)
758 find_source_lines (current_source_symtab
, desc
);
760 if (line
< 1 || line
> current_source_symtab
->nlines
)
763 error ("Expression not found");
766 if (lseek (desc
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
769 perror_with_name (current_source_symtab
->filename
);
772 stream
= fdopen (desc
, "r");
776 char buf
[4096]; /* Should be reasonable??? */
777 register char *p
= buf
;
784 } while (c
!= '\n' && (c
= fgetc (stream
)) >= 0);
786 /* We now have a source line in buf; null terminate and match. */
788 if (re_exec (buf
) > 0)
792 print_source_lines (current_source_symtab
,
794 current_source_line
= max (line
- 5, 1);
798 if (fseek (stream
, current_source_symtab
->line_charpos
[line
- 1], 0) < 0)
801 perror_with_name (current_source_symtab
->filename
);
805 printf ("Expression not found\n");
813 current_source_symtab
= 0;
816 add_com ("directory", class_files
, directory_command
,
817 "Add directory DIR to end of search path for source files.\n\
818 With no argument, reset the search path to just the working directory\n\
819 and forget cached info on line positions in source files.");
821 add_info ("directories", directories_info
,
822 "Current search path for finding source files.");
824 add_info ("line", line_info
,
825 "Core addresses of the code for a source line.\n\
826 Line can be specified as\n\
827 LINENUM, to list around that line in current file,\n\
828 FILE:LINENUM, to list around that line in that file,\n\
829 FUNCTION, to list around beginning of that function,\n\
830 FILE:FUNCTION, to distinguish among like-named static functions.\n\
831 Default is to describe the last source line that was listed.\n\n\
832 This sets the default address for \"x\" to the line's first instruction\n\
833 so that \"x/i\" suffices to start examining the machine code.\n\
834 The address is also stored as the value of \"$_\".");
836 add_com ("forward-search", class_files
, forward_search_command
,
837 "Search for regular expression (see regex(3)) from last line listed.");
838 add_com_alias ("search", "forward-search", class_files
, 0);
840 add_com ("reverse-search", class_files
, reverse_search_command
,
841 "Search backward for regular expression (see regex(3)) from last line listed.");
843 add_com ("list", class_files
, list_command
,
844 "List specified function or line.\n\
845 With no argument, lists ten more lines after or around previous listing.\n\
846 \"list -\" lists the ten lines before a previous ten-line listing.\n\
847 One argument specifies a line, and ten lines are listed around that line.\n\
848 Two arguments with comma between specify starting and ending lines to list.\n\
849 Lines can be specified in these ways:\n\
850 LINENUM, to list around that line in current file,\n\
851 FILE:LINENUM, to list around that line in that file,\n\
852 FUNCTION, to list around beginning of that function,\n\
853 FILE:FUNCTION, to distinguish among like-named static functions.\n\
854 *ADDRESS, to list around the line containing that address.\n\
855 With two args if one is empty it stands for ten lines away from the other arg.");