📄 source.c
字号:
setfile_command(arg, from_tty); /* if we got back, command was successful */ i = push_stack_ptr; push_stack[i].symtab = cursym; push_stack[i].line = curline; push_stack_ptr = (i + 1) & (PUSH_STACK_SIZE - 1);}static voidpop_file_command (arg, from_tty) char *arg; int from_tty;{ register unsigned int i = push_stack_ptr; /* if there's something on the stack, pop it & clear the slot. */ i = (i + (PUSH_STACK_SIZE - 1)) & (PUSH_STACK_SIZE - 1); if (push_stack[i].symtab) { current_source_symtab = push_stack[i].symtab; first_line_listed = current_source_line = push_stack[i].line; push_stack[i].symtab = NULL; push_stack_ptr = i; }}static voidlist_command (arg, from_tty) char *arg; int from_tty;{ struct symtabs_and_lines sals, sals_end; struct symtab_and_line sal, sal_end; struct symbol *sym; char *arg1; int no_end = 1; int dummy_end = 0; int dummy_beg = 0; int linenum_beg = 0; char *p; if (!have_full_symbols () && !have_partial_symbols()) error ("No symbol table is loaded. Use the \"file\" command."); /* Pull in a current source symtab if necessary */ if (current_source_symtab == 0 && (arg == 0 || arg[0] == '+' || arg[0] == '-')) select_source_symtab (0); /* "l" or "l +" lists next ten lines. */ if (arg == 0 || !strcmp (arg, "+")) { if (current_source_symtab == 0) error ("No default source file yet. Do \"help list\"."); print_source_lines (current_source_symtab, current_source_line, current_source_line + lines_to_list, 0); return; } /* "l -" lists previous ten lines, the ones before the ten just listed. */ if (!strcmp (arg, "-")) { if (current_source_symtab == 0) error ("No default source file yet. Do \"help list\"."); print_source_lines (current_source_symtab, max (first_line_listed - lines_to_list, 1), first_line_listed, 0); return; } /* Now if there is only one argument, decode it in SAL and set NO_END. If there are two arguments, decode them in SAL and SAL_END and clear NO_END; however, if one of the arguments is blank, set DUMMY_BEG or DUMMY_END to record that fact. */ arg1 = arg; if (*arg1 == ',') dummy_beg = 1; else { sals = decode_line_1 (&arg1, 0, 0, 0); if (! sals.nelts) return; /* C++ */ if (sals.nelts > 1) { ambiguous_line_spec (&sals); free (sals.sals); return; } sal = sals.sals[0]; free (sals.sals); } /* Record whether the BEG arg is all digits. */ for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++); linenum_beg = (p == arg1); while (*arg1 == ' ' || *arg1 == '\t') arg1++; if (*arg1 == ',') { no_end = 0; arg1++; while (*arg1 == ' ' || *arg1 == '\t') arg1++; if (*arg1 == 0) dummy_end = 1; else { if (dummy_beg) sals_end = decode_line_1 (&arg1, 0, 0, 0); else sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line); if (sals_end.nelts == 0) return; if (sals_end.nelts > 1) { ambiguous_line_spec (&sals_end); free (sals_end.sals); return; } sal_end = sals_end.sals[0]; free (sals_end.sals); } } if (*arg1) error ("Junk at end of line specification."); if (!no_end && !dummy_beg && !dummy_end && sal.symtab != sal_end.symtab) error ("Specified start and end are in different files."); if (dummy_beg && dummy_end) error ("Two empty args do not say what lines to list."); /* if line was specified by address, first print exactly which line, and which file. In this case, sal.symtab == 0 means address is outside of all known source files, not that user failed to give a filename. */ if (*arg == '*') { if (sal.symtab == 0) error ("No source file for address %s.", local_hex_string(sal.pc)); sym = find_pc_function (sal.pc); if (sym) { printf_filtered ("%s is in ", local_hex_string(sal.pc)); fprint_symbol (stdout, SYMBOL_NAME (sym)); printf_filtered (" (%s:%d).\n", sal.symtab->filename, sal.line); } else printf_filtered ("%s is at %s:%d.\n", local_hex_string(sal.pc), sal.symtab->filename, sal.line); } /* If line was not specified by just a line number, and it does not imply a symtab, it must be an undebuggable symbol which means no source code. */ if (! linenum_beg && sal.symtab == 0) error ("No line number known for %s.", arg); /* If this command is repeated with RET, turn it into the no-arg variant. */ if (from_tty) *arg = 0; if (dummy_beg && sal_end.symtab == 0) error ("No default source file yet. Do \"help list\"."); if (dummy_beg) print_source_lines (sal_end.symtab, max (sal_end.line - (lines_to_list - 1), 1), sal_end.line + 1, 0); else if (sal.symtab == 0) error ("No default source file yet. Do \"help list\"."); else if (no_end) print_source_lines (sal.symtab, max (sal.line - (lines_to_list / 2), 1), sal.line + (lines_to_list / 2), 0); else print_source_lines (sal.symtab, sal.line, (dummy_end ? sal.line + lines_to_list : sal_end.line + 1), 0);}/* Print info on range of pc's in a specified line. */static voidline_info (arg, from_tty) char *arg; int from_tty;{ struct symtabs_and_lines sals; struct symtab_and_line sal; CORE_ADDR start_pc, end_pc; int i; if (arg == 0) { sal.symtab = current_source_symtab; sal.line = last_line_listed; sals.nelts = 1; sals.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); sals.sals[0] = sal; } else { sals = decode_line_spec_1 (arg, 0); /* If this command is repeated with RET, turn it into the no-arg variant. */ if (from_tty) *arg = 0; } /* C++ More than one line may have been specified, as when the user specifies an overloaded function name. Print info on them all. */ for (i = 0; i < sals.nelts; i++) { sal = sals.sals[i]; if (sal.symtab == 0) error ("No source file specified."); if (sal.line > 0 && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc)) { if (start_pc == end_pc) printf_filtered ("Line %d of \"%s\" is at pc %s but contains no code.\n", sal.line, sal.symtab->filename, local_hex_string(start_pc)); else { printf_filtered ("Line %d of \"%s\" starts at pc %s", sal.line, sal.symtab->filename, local_hex_string(start_pc)); printf_filtered (" and ends at %s.\n", local_hex_string(end_pc)); } /* x/i should display this line's code. */ set_next_address (start_pc); /* Repeating "info line" should do the following line. */ last_line_listed = sal.line + 1; } else printf_filtered ("Line number %d is out of range for \"%s\".\n", sal.line, sal.symtab->filename); }}/* Commands to search the source file for a regexp. *//* ARGSUSED */static voidforward_search_command (regex, from_tty) char *regex; int from_tty;{ register int c; register int desc; register FILE *stream; int line = last_line_listed + 1; char *msg; msg = (char *) re_comp (regex); if (msg) error (msg); if (current_source_symtab == 0) select_source_symtab (0); /* Search from last_line_listed+1 in current_source_symtab */ desc = open_source_file (current_source_symtab); if (desc < 0) perror_with_name (current_source_symtab->filename); if (current_source_symtab->line_charpos == 0) find_source_lines (current_source_symtab, desc); if (line < 1 || line > current_source_symtab->nlines) { close (desc); error ("Expression not found"); } if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) { close (desc); perror_with_name (current_source_symtab->filename); } stream = fdopen (desc, "r"); clearerr (stream); while (1) {/* FIXME!!! We walk right off the end of buf if we get a long line!!! */ char buf[4096]; /* Should be reasonable??? */ register char *p = buf; c = getc (stream); if (c == EOF) break; do { *p++ = c; } while (c != '\n' && (c = getc (stream)) >= 0); /* we now have a source line in buf, null terminate and match */ *p = 0; if (re_exec (buf) > 0) { /* Match! */ fclose (stream); print_source_lines (current_source_symtab, line, line+1, 0); current_source_line = max (line - lines_to_list / 2, 1); return; } line++; } printf_filtered ("Expression not found\n"); fclose (stream);}/* ARGSUSED */static voidreverse_search_command (regex, from_tty) char *regex; int from_tty;{ register int c; register int desc; register FILE *stream; int line = last_line_listed - 1; char *msg; msg = (char *) re_comp (regex); if (msg) error (msg); if (current_source_symtab == 0) select_source_symtab (0); /* Search from last_line_listed-1 in current_source_symtab */ desc = open_source_file (current_source_symtab); if (desc < 0) perror_with_name (current_source_symtab->filename); if (current_source_symtab->line_charpos == 0) find_source_lines (current_source_symtab, desc); if (line < 1 || line > current_source_symtab->nlines) { close (desc); error ("Expression not found"); } if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) { close (desc); perror_with_name (current_source_symtab->filename); } stream = fdopen (desc, "r"); clearerr (stream); while (line > 1) {/* FIXME!!! We walk right off the end of buf if we get a long line!!! */ char buf[4096]; /* Should be reasonable??? */ register char *p = buf; c = getc (stream); if (c == EOF) break; do { *p++ = c; } while (c != '\n' && (c = getc (stream)) >= 0); /* We now have a source line in buf; null terminate and match. */ *p = 0; if (re_exec (buf) > 0) { /* Match! */ fclose (stream); print_source_lines (current_source_symtab, line, line+1, 0); current_source_line = max (line - lines_to_list / 2, 1); return; } line--; if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0) { fclose (stream); perror_with_name (current_source_symtab->filename); } } printf_filtered ("Expression not found\n"); fclose (stream); return;}void_initialize_source (){ current_source_symtab = 0; init_source_path (); add_com ("directory", class_files, directory_command, "Add directory DIR to beginning of search path for source files.\n\Forget cached info on source file locations and line positions.\n\DIR can also be $cwd for the current working directory, or $cdir for the\n\directory in which the source file was compiled into object code.\n\With no argument, reset the search path to $cdir:$cwd, the default."); add_cmd ("directories", no_class, show_directories, "Current search path for finding source files.\n\$cwd in the path means the current working directory.\n\$cdir in the path means the compilation directory of the source file.", &showlist); add_info ("source", source_info, "Information about the current source file."); add_info ("line", line_info, "Core addresses of the code for a source line.\n\Line can be specified as\n\ LINENUM, to list around that line in current file,\n\ FILE:LINENUM, to list around that line in that file,\n\ FUNCTION, to list around beginning of that function,\n\ FILE:FUNCTION, to distinguish among like-named static functions.\n\Default is to describe the last source line that was listed.\n\n\This sets the default address for \"x\" to the line's first instruction\n\so that \"x/i\" suffices to start examining the machine code.\n\The address is also stored as the value of \"$_\"."); add_com ("forward-search", class_files, forward_search_command, "Search for regular expression (see regex(3)) from last line listed."); add_com_alias ("search", "forward-search", class_files, 0); add_com ("reverse-search", class_files, reverse_search_command, "Search backward for regular expression (see regex(3)) from last line listed."); add_com ("list", class_files, list_command, "List specified function or line.\n\With no argument, lists ten more lines after or around previous listing.\n\\"list -\" lists the ten lines before a previous ten-line listing.\n\One argument specifies a line, and ten lines are listed around that line.\n\Two arguments with comma between specify starting and ending lines to list.\n\Lines can be specified in these ways:\n\ LINENUM, to list around that line in current file,\n\ FILE:LINENUM, to list around that line in that file,\n\ FUNCTION, to list around beginning of that function,\n\ FILE:FUNCTION, to distinguish among like-named static functions.\n\ *ADDRESS, to list around the line containing that address.\n\With two args if one is empty it stands for ten lines away from the other arg."); add_com_alias ("l", "list", class_files, 1); add_show_from_set (add_set_cmd ("listsize", class_support, var_uinteger, (char *)&lines_to_list, "Set number of source lines gdb will list by default.", &setlist), &showlist); add_com ("setfile", class_files, setfile_command, "Select current file, function and line for display or list.\n\Specification can have the form:\n\ LINENUM, to select that line in current file,\n\ FILE:LINENUM, to select that line in that file,\n\ FUNCTION, to select beginning of that function,\n\ FILE:FUNCTION, to distinguish among like-named static functions.\n\ *ADDRESS, to select the line containing that address."); add_com ("push-to-file", class_files, push_to_file_command, "Like \"file\" command but remembers current file & line on a stack.\n\Can later return to current file with \"pop-file\" command.\n\Up to 32 file positions can be pushed on stack."); add_com ("pop-file", class_files, pop_file_command, "Pops back to file position saved by most recent \"push-to-file\".\n\If everything has been popped from stack, command does nothing.");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -