⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stack.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
      fprintf_filtered (stream, "No symbol table info available.\n");      return;    }  b = SYMBOL_BLOCK_VALUE (func);  nsyms = BLOCK_NSYMS (b);  for (i = 0; i < nsyms; i++)    {      sym = BLOCK_SYM (b, i);      if (SYMBOL_CLASS (sym) == LOC_ARG	  || SYMBOL_CLASS (sym) == LOC_LOCAL_ARG	  || SYMBOL_CLASS (sym) == LOC_REF_ARG	  || SYMBOL_CLASS (sym) == LOC_REGPARM)	{	  values_printed = 1;	  fprint_symbol (stream, SYMBOL_NAME (sym));	  fputs_filtered (" = ", stream);	  /* We have to look up the symbol because arguments often have	     two entries (one a parameter, one a register) and the one	     we want is the register, which lookup_symbol will find for	     us.  */	  sym2 = lookup_symbol (SYMBOL_NAME (sym),			b, VAR_NAMESPACE, (int *)NULL, (struct symtab **)NULL);	  print_variable_value (sym2, frame, stream);	  fprintf_filtered (stream, "\n");	}    }  if (!values_printed)    {      fprintf_filtered (stream, "No arguments.\n");    }}static voidargs_info (ignore, from_tty)     char *ignore;     int from_tty;{  if (!selected_frame)    error ("No frame selected.");  print_frame_arg_vars (selected_frame, stdout);}/* Select frame FRAME, and note that its stack level is LEVEL.   LEVEL may be -1 if an actual level number is not known.  */voidselect_frame (frame, level)     FRAME frame;     int level;{  register struct symtab *s;  selected_frame = frame;  selected_frame_level = level;  /* Ensure that symbols for this frame are read in.  Also, determine the     source language of this frame, and switch to it if desired.  */  if (frame)  {    s = find_pc_symtab (get_frame_info (frame)->pc);    if (s 	&& s->language != current_language->la_language	&& s->language != language_unknown	&& language_mode == language_mode_auto) {      set_language(s->language);    }  }}/* Store the selected frame and its level into *FRAMEP and *LEVELP.   If there is no selected frame, *FRAMEP is set to NULL.  */voidrecord_selected_frame (frameaddrp, levelp)     FRAME_ADDR *frameaddrp;     int *levelp;{  *frameaddrp = selected_frame ? FRAME_FP (selected_frame) : 0;  *levelp = selected_frame_level;}/* Return the symbol-block in which the selected frame is executing.   Can return zero under various legitimate circumstances.  */struct block *get_selected_block (){  if (!target_has_stack)    return 0;  if (!selected_frame)    return get_current_block ();  return get_frame_block (selected_frame);}/* Find a frame a certain number of levels away from FRAME.   LEVEL_OFFSET_PTR points to an int containing the number of levels.   Positive means go to earlier frames (up); negative, the reverse.   The int that contains the number of levels is counted toward   zero as the frames for those levels are found.   If the top or bottom frame is reached, that frame is returned,   but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates   how much farther the original request asked to go.  */FRAMEfind_relative_frame (frame, level_offset_ptr)     register FRAME frame;     register int* level_offset_ptr;{  register FRAME prev;  register FRAME frame1;  /* Going up is simple: just do get_prev_frame enough times     or until initial frame is reached.  */  while (*level_offset_ptr > 0)    {      prev = get_prev_frame (frame);      if (prev == 0)	break;      (*level_offset_ptr)--;      frame = prev;    }  /* Going down is just as simple.  */  if (*level_offset_ptr < 0)    {      while (*level_offset_ptr < 0) {	frame1 = get_next_frame (frame);	if (!frame1)	  break;	frame = frame1;	(*level_offset_ptr)++;      }    }  return frame;}/* The "select_frame" command.  With no arg, NOP.   With arg LEVEL_EXP, select the frame at level LEVEL if it is a   valid level.  Otherwise, treat level_exp as an address expression   and select it.  See parse_frame_specification for more info on proper   frame expressions. *//* ARGSUSED */static voidselect_frame_command (level_exp, from_tty)     char *level_exp;     int from_tty;{  register FRAME frame, frame1;  unsigned int level = 0;  if (!target_has_stack)    error ("No stack.");  frame = parse_frame_specification (level_exp);  /* Try to figure out what level this frame is.  But if there is     no current stack, don't error out -- let the user set one.  */  frame1 = 0;  if (get_current_frame()) {    for (frame1 = get_prev_frame (0);	 frame1 && frame1 != frame;	 frame1 = get_prev_frame (frame1))      level++;  }  if (!frame1)    level = 0;  select_frame (frame, level);}/* The "frame" command.  With no arg, print selected frame briefly.   With arg, behaves like select_frame and then prints the selected   frame.  */static voidframe_command (level_exp, from_tty)     char *level_exp;     int from_tty;{  select_frame_command (level_exp, from_tty);  print_stack_frame (selected_frame, selected_frame_level, 1);}/* Select the frame up one or COUNT stack levels   from the previously selected frame, and print it briefly.  *//* ARGSUSED */static voidup_silently_command (count_exp, from_tty)     char *count_exp;     int from_tty;{  register FRAME frame;  int count = 1, count1;  if (count_exp)    count = parse_and_eval_address (count_exp);  count1 = count;    if (target_has_stack == 0 || selected_frame == 0)    error ("No stack.");  frame = find_relative_frame (selected_frame, &count1);  if (count1 != 0 && count_exp == 0)    error ("Initial frame selected; you cannot go up.");  select_frame (frame, selected_frame_level + count - count1);}static voidup_command (count_exp, from_tty)     char *count_exp;     int from_tty;{  up_silently_command (count_exp, from_tty);  print_stack_frame (selected_frame, selected_frame_level, 1);}/* Select the frame down one or COUNT stack levels   from the previously selected frame, and print it briefly.  *//* ARGSUSED */static voiddown_silently_command (count_exp, from_tty)     char *count_exp;     int from_tty;{  register FRAME frame;  int count = -1, count1;  if (count_exp)    count = - parse_and_eval_address (count_exp);  count1 = count;    if (target_has_stack == 0 || selected_frame == 0)    error ("No stack.");  frame = find_relative_frame (selected_frame, &count1);  if (count1 != 0 && count_exp == 0)    error ("Bottom (i.e., innermost) frame selected; you cannot go down.");  select_frame (frame, selected_frame_level + count - count1);}static voiddown_command (count_exp, from_tty)     char *count_exp;     int from_tty;{  down_silently_command (count_exp, from_tty);  print_stack_frame (selected_frame, selected_frame_level, 1);}static voidreturn_command (retval_exp, from_tty)     char *retval_exp;     int from_tty;{  struct symbol *thisfun;  FRAME_ADDR selected_frame_addr;  CORE_ADDR selected_frame_pc;  FRAME frame;  char *funcname;  struct cleanup *back_to;  value return_value;  if (selected_frame == NULL)    error ("No selected frame.");  thisfun = get_frame_function (selected_frame);  selected_frame_addr = FRAME_FP (selected_frame);  selected_frame_pc = (get_frame_info (selected_frame))->pc;  /* Compute the return value (if any -- possibly getting errors here).     Call VALUE_CONTENTS to make sure we have fully evaluated it, since     it might live in the stack frame we're about to pop.  */  if (retval_exp)    {      return_value = parse_and_eval (retval_exp);      VALUE_CONTENTS (return_value);    }  /* If interactive, require confirmation.  */  if (from_tty)    {      if (thisfun != 0)	{	  funcname = strdup_demangled (SYMBOL_NAME (thisfun));	  back_to = make_cleanup (free, funcname);	  if (!query ("Make %s return now? ", funcname))	    {	      error ("Not confirmed.");	      /* NOTREACHED */	    }	  do_cleanups (back_to);	}      else	if (!query ("Make selected stack frame return now? "))	  error ("Not confirmed.");    }  /* Do the real work.  Pop until the specified frame is current.  We     use this method because the selected_frame is not valid after     a POP_FRAME.  The pc comparison makes this work even if the     selected frame shares its fp with another frame.  */  while ( selected_frame_addr != FRAME_FP (frame = get_current_frame())       || selected_frame_pc   != (get_frame_info (frame))->pc  )    POP_FRAME;  /* Then pop that frame.  */  POP_FRAME;  /* Compute the return value (if any) and store in the place     for return values.  */  if (retval_exp)    set_return_value (return_value);  /* If interactive, print the frame that is now current.  */  if (from_tty)    frame_command ("0", 1);}/* Gets the language of the current frame. */enum languageget_frame_language(){   register struct symtab *s;   FRAME fr;   enum language flang;		/* The language of the current frame */      fr = get_frame_info(selected_frame);   if(fr)   {      s = find_pc_symtab(fr->pc);      if(s)	 flang = s->language;      else	 flang = language_unknown;   }   else      flang = language_unknown;   return flang;}static voidprintsource_command (retval_exp, from_tty)     char *retval_exp;     int from_tty;{	if (info_printsource)		++print_source_at_stop;	else		--print_source_at_stop;}void_initialize_stack (){  struct cmd_list_element *c;#if 0    backtrace_limit = 30;#endif  add_com ("return", class_stack, return_command,	   "Make selected stack frame return to its caller.\n\Control remains in the debugger, but when you continue\n\execution will resume in the frame above the one now selected.\n\If an argument is given, it is an expression for the value to return.");  add_com ("up", class_stack, up_command,	   "Select and print stack frame that called this one.\n\An argument says how many frames up to go.");  add_com ("up-silently", class_support, up_silently_command,	   "Same as the `up' command, but does not print anything.\n\This is useful in command scripts.");  add_com ("down", class_stack, down_command,	   "Select and print stack frame called by this one.\n\An argument says how many frames down to go.");  add_com_alias ("do", "down", class_stack, 1);  add_com_alias ("dow", "down", class_stack, 1);  add_com ("down-silently", class_support, down_silently_command,	   "Same as the `down' command, but does not print anything.\n\This is useful in command scripts.");  add_com ("frame", class_stack, frame_command,	   "Select and print a stack frame.\n\With no argument, print the selected stack frame.  (See also \"info frame\").\n\An argument specifies the frame to select.\n\It can be a stack frame number or the address of the frame.\n\With argument, nothing is printed if input is coming from\n\a command file or a user-defined command.");  add_com_alias ("f", "frame", class_stack, 1);  add_com ("select-frame", class_stack, select_frame_command,	   "Select a stack frame without printing anything.\n\An argument specifies the frame to select.\n\It can be a stack frame number or the address of the frame.\n");  add_com ("backtrace", class_stack, backtrace_command,	   "Print backtrace of all stack frames, or innermost COUNT frames.\n\With a negative argument, print outermost -COUNT frames.");  add_com_alias ("bt", "backtrace", class_stack, 0);  add_com_alias ("where", "backtrace", class_alias, 0);  add_info ("stack", backtrace_command,	    "Backtrace of the stack, or innermost COUNT frames.");  add_info_alias ("s", "stack", 1);  add_info ("frame", frame_info,	    "All about selected stack frame, or frame at ADDR.");  add_info_alias ("f", "frame", 1);  add_info ("locals", locals_info,	    "Local variables of current stack frame.");  add_info ("args", args_info,	    "Argument variables of current stack frame.");  add_info ("catch", catch_info,	    "Exceptions that can be caught in the current stack frame.");#if 0  add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command, 	   "Specify maximum number of frames for \"backtrace\" to print by default.",	   &setlist);  add_info ("backtrace-limit", backtrace_limit_info,	    "The maximum number of frames for \"backtrace\" to print by default.");#endif  c = add_set_cmd("printsource", class_stack, var_boolean,		  (char *)&info_printsource,		  "Set auto print of source lines at step/breakpoint.",		  &setlist),  add_show_from_set(c, &showlist);  c->function.sfunc = printsource_command;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -