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

📄 breakpoint.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
		    fputs_filtered ("in ", stdout);		    fputs_demangled (SYMBOL_NAME (sym), stdout, 				     DMGL_ANSI | DMGL_PARAMS);		    fputs_filtered (" at ", stdout);		  }		fputs_filtered (b->symtab->filename, stdout);		printf_filtered (":%d", b->line_number);	      }	    else	      print_address_symbolic (b->address, stdout, demangle, " ");	  }	printf_filtered ("\n");	if (b->frame)	  printf_filtered ("\tstop only in stack frame at %s\n",			   local_hex_string(b->frame));	if (b->cond)	  {	    printf_filtered ("\tstop only if ");	    print_expression (b->cond, stdout);	    printf_filtered ("\n");	  }	if (b->ignore_count)	  printf_filtered ("\tignore next %d hits\n", b->ignore_count);	if ((l = b->commands))	  while (l)	    {	      fputs_filtered ("\t", stdout);	      fputs_filtered (l->line, stdout);	      fputs_filtered ("\n", stdout);	      l = l->next;	    }      }  if (!found_a_breakpoint      && bnum != -1)    printf_filtered ("No breakpoint or watchpoint number %d.\n", bnum);  else    /* Compare against (CORE_ADDR)-1 in case some compiler decides       that a comparison of an unsigned with -1 is always false.  */    if (last_addr != (CORE_ADDR)-1)      set_next_address (last_addr);}/* ARGSUSED */static voidbreakpoints_info (bnum_exp, from_tty)     char *bnum_exp;     int from_tty;{  int bnum = -1;  if (bnum_exp)    bnum = parse_and_eval_address (bnum_exp);  breakpoint_1 (bnum, 0);}#if MAINTENANCE_CMDS/* ARGSUSED */static voidmaintenance_info_breakpoints (bnum_exp, from_tty)     char *bnum_exp;     int from_tty;{  int bnum = -1;  if (bnum_exp)    bnum = parse_and_eval_address (bnum_exp);  breakpoint_1 (bnum, 1);}#endif/* Print a message describing any breakpoints set at PC.  */static voiddescribe_other_breakpoints (pc)     register CORE_ADDR pc;{  register int others = 0;  register struct breakpoint *b;  ALL_BREAKPOINTS (b)    if (b->address == pc)      others++;  if (others > 0)    {      printf ("Note: breakpoint%s ", (others > 1) ? "s" : "");      ALL_BREAKPOINTS (b)	if (b->address == pc)	  {	    others--;	    printf ("%d%s%s ",		    b->number,		    (b->enable == disabled) ? " (disabled)" : "",		    (others > 1) ? "," : ((others == 1) ? " and" : ""));	  }      printf ("also set at pc %s.\n", local_hex_string(pc));    }}/* Set the default place to put a breakpoint   for the `break' command with no arguments.  */voidset_default_breakpoint (valid, addr, symtab, line)     int valid;     CORE_ADDR addr;     struct symtab *symtab;     int line;{  default_breakpoint_valid = valid;  default_breakpoint_address = addr;  default_breakpoint_symtab = symtab;  default_breakpoint_line = line;}/* Rescan breakpoints at address ADDRESS,   marking the first one as "first" and any others as "duplicates".   This is so that the bpt instruction is only inserted once.  */static voidcheck_duplicates (address)     CORE_ADDR address;{  register struct breakpoint *b;  register int count = 0;  if (address == 0)		/* Watchpoints are uninteresting */    return;  ALL_BREAKPOINTS (b)    if (b->enable != disabled && b->address == address)      {	count++;	b->duplicate = count > 1;      }}/* Low level routine to set a breakpoint.   Takes as args the three things that every breakpoint must have.   Returns the breakpoint object so caller can set other things.   Does not set the breakpoint number!   Does not print anything.   ==> This routine should not be called if there is a chance of later   error(); otherwise it leaves a bogus breakpoint on the chain.  Validate   your arguments BEFORE calling this routine!  */static struct breakpoint *set_raw_breakpoint (sal)     struct symtab_and_line sal;{  register struct breakpoint *b, *b1;  b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));  memset (b, 0, sizeof (*b));  b->address = sal.pc;  b->symtab = sal.symtab;  b->line_number = sal.line;  b->enable = enabled;  b->next = 0;  b->silent = 0;  b->ignore_count = 0;  b->commands = NULL;  b->frame = 0;  /* Add this breakpoint to the end of the chain     so that a list of breakpoints will come out in order     of increasing numbers.  */  b1 = breakpoint_chain;  if (b1 == 0)    breakpoint_chain = b;  else    {      while (b1->next)	b1 = b1->next;      b1->next = b;    }  check_duplicates (sal.pc);  return b;}static voidcreate_longjmp_breakpoint(func_name)     char *func_name;{  struct symtab_and_line sal;  struct breakpoint *b;  static int internal_breakpoint_number = -1;  if (func_name != NULL)    {      struct minimal_symbol *m;      m = lookup_minimal_symbol(func_name, (struct objfile *)NULL);      if (m)	sal.pc = m->address;      else	return;    }  else    sal.pc = 0;  sal.symtab = NULL;  sal.line = 0;  b = set_raw_breakpoint(sal);  if (!b) return;  b->type = func_name != NULL ? bp_longjmp : bp_longjmp_resume;  b->disposition = donttouch;  b->enable = disabled;  b->silent = 1;  if (func_name)    b->addr_string = strsave(func_name);  b->number = internal_breakpoint_number--;}/* Call this routine when stepping and nexting to enable a breakpoint if we do   a longjmp().  When we hit that breakpoint, call   set_longjmp_resume_breakpoint() to figure out where we are going. */voidenable_longjmp_breakpoint(){  register struct breakpoint *b;  ALL_BREAKPOINTS (b)    if (b->type == bp_longjmp)      {	b->enable = enabled;	check_duplicates (b->address);      }}voiddisable_longjmp_breakpoint(){  register struct breakpoint *b;  ALL_BREAKPOINTS (b)    if (   b->type == bp_longjmp	|| b->type == bp_longjmp_resume)      {	b->enable = disabled;	check_duplicates (b->address);      }}/* Call this after hitting the longjmp() breakpoint.  Use this to set a new   breakpoint at the target of the jmp_buf.   FIXME - This ought to be done by setting a temporary breakpoint that gets   deleted automatically...*/voidset_longjmp_resume_breakpoint(pc, frame)     CORE_ADDR pc;     FRAME frame;{  register struct breakpoint *b;  ALL_BREAKPOINTS (b)    if (b->type == bp_longjmp_resume)      {	b->address = pc;	b->enable = enabled;	if (frame != NULL)	  b->frame = FRAME_FP(frame);	else	  b->frame = 0;	check_duplicates (b->address);	return;      }}/* Set a breakpoint that will evaporate an end of command   at address specified by SAL.   Restrict it to frame FRAME if FRAME is nonzero.  */struct breakpoint *set_momentary_breakpoint (sal, frame, type)     struct symtab_and_line sal;     FRAME frame;     enum bptype type;{  register struct breakpoint *b;  b = set_raw_breakpoint (sal);  b->type = type;  b->enable = enabled;  b->disposition = donttouch;  b->frame = (frame ? FRAME_FP (frame) : 0);  return b;}#if 0voidclear_momentary_breakpoints (){  register struct breakpoint *b;  ALL_BREAKPOINTS (b)    if (b->disposition == delete)      {	delete_breakpoint (b);	break;      }}#endif/* Tell the user we have just set a breakpoint B.  */static voidmention (b)     struct breakpoint *b;{  switch (b->type)    {    case bp_watchpoint:      printf_filtered ("Watchpoint %d: ", b->number);      print_expression (b->exp, stdout);      break;    case bp_breakpoint:      printf_filtered ("Breakpoint %d at %s", b->number,		       local_hex_string(b->address));      if (b->symtab)	printf_filtered (": file %s, line %d.",			 b->symtab->filename, b->line_number);      break;    case bp_until:    case bp_finish:    case bp_longjmp:    case bp_longjmp_resume:      break;    }  printf_filtered ("\n");}#if 0/* Nobody calls this currently. *//* Set a breakpoint from a symtab and line.   If TEMPFLAG is nonzero, it is a temporary breakpoint.   ADDR_STRING is a malloc'd string holding the name of where we are   setting the breakpoint.  This is used later to re-set it after the   program is relinked and symbols are reloaded.   Print the same confirmation messages that the breakpoint command prints.  */voidset_breakpoint (s, line, tempflag, addr_string)     struct symtab *s;     int line;     int tempflag;     char *addr_string;{  register struct breakpoint *b;  struct symtab_and_line sal;    sal.symtab = s;  sal.line = line;  sal.pc = 0;  resolve_sal_pc (&sal);			/* Might error out */  describe_other_breakpoints (sal.pc);  b = set_raw_breakpoint (sal);  set_breakpoint_count (breakpoint_count + 1);  b->number = breakpoint_count;  b->type = bp_breakpoint;  b->cond = 0;  b->addr_string = addr_string;  b->enable = enabled;  b->disposition = tempflag ? delete : donttouch;  mention (b);}#endif /* 0 *//* Set a breakpoint according to ARG (function, linenum or *address)   and make it temporary if TEMPFLAG is nonzero. */static voidbreak_command_1 (arg, tempflag, from_tty)     char *arg;     int tempflag, from_tty;{  struct symtabs_and_lines sals;  struct symtab_and_line sal;  register struct expression *cond = 0;  register struct breakpoint *b;  /* Pointers in arg to the start, and one past the end, of the condition.  */  char *cond_start = NULL;  char *cond_end;  /* Pointers in arg to the start, and one past the end,     of the address part.  */  char *addr_start = NULL;  char *addr_end;    int i;  sals.sals = NULL;  sals.nelts = 0;  sal.line = sal.pc = sal.end = 0;  sal.symtab = 0;  /* If no arg given, or if first arg is 'if ', use the default breakpoint. */  if (!arg || (arg[0] == 'i' && arg[1] == 'f' 	       && (arg[2] == ' ' || arg[2] == '\t')))    {      if (default_breakpoint_valid)	{	  sals.sals = (struct symtab_and_line *) 	    xmalloc (sizeof (struct symtab_and_line));	  sal.pc = default_breakpoint_address;	  sal.line = default_breakpoint_line;	  sal.symtab = default_breakpoint_symtab;	  sals.sals[0] = sal;	  sals.nelts = 1;	}      else	error ("No default breakpoint address now.");    }  else    {      addr_start = arg;      /* Force almost all breakpoints to be in terms of the	 current_source_symtab (which is decode_line_1's default).  This	 should produce the results we want almost all of the time while	 leaving default_breakpoint_* alone.  */      if (default_breakpoint_valid	  && (!current_source_symtab	      || (arg && (*arg == '+' || *arg == '-'))))	sals = decode_line_1 (&arg, 1, default_breakpoint_symtab,			      default_breakpoint_line);      else	sals = decode_line_1 (&arg, 1, (struct symtab *)NULL, 0);      addr_end = arg;    }    if (! sals.nelts)     return;  /* Resolve all line numbers to PC's, and verify that conditions     can be parsed, before setting any breakpoints.  */  for (i = 0; i < sals.nelts; i++)    {      resolve_sal_pc (&sals.sals[i]);            while (arg && *arg)	{	  if (arg[0] == 'i' && arg[1] == 'f'	      && (arg[2] == ' ' || arg[2] == '\t'))	    {	      arg += 2;	      cond_start = arg;	      cond = parse_exp_1 (&arg, block_for_pc (sals.sals[i].pc), 0);	      cond_end = arg;	    }	  else	    error ("Junk at end of arguments.");	}    }  /* Now set all the breakpoints.  */  for (i = 0; i < sals.nelts; i++)    {      sal = sals.sals[i];      if (from_tty)	describe_other_breakpoints (sal.pc);      b = set_raw_breakpoint (sal);      set_breakpoint_count (breakpoint_count + 1);      b->number = breakpoint_count;      b->type = bp_breakpoint;      b->cond = cond;            if (addr_start)	b->addr_string = savestring (addr_start, addr_end - addr_start);      if (cond_start)	b->cond_string = savestring (cond_start, cond_end - cond_start);				           b->enable = enabled;      b->disposition = tempflag ? delete : donttouch;      mention (b);    }  if (sals.nelts > 1)    {      printf ("Multiple breakpoints were set.\n");      printf ("Use the \"delete\" command to delete unwanted breakpoints.\n");    }  free ((PTR)sals.sals);}/* Helper function for break_command_1 and disassemble_command.  */voidresolve_sal_pc (sal)     struct symtab_and_line *sal;{  CORE_ADDR pc;  if (sal->pc == 0 && sal->symtab != 0)    {      pc = find_line_pc (sal->symtab, sal->line);      if (pc == 0)	error ("No line %d in file \"%s\".",	       sal->line, sal->symtab->filename);      sal->pc = pc;    }}voidbreak_command (arg, from_tty)

⌨️ 快捷键说明

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