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

📄 procfs.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
LOCAL FUNCTION	procfs_resume -- resume execution of the inferior processSYNOPSIS	void procfs_resume (int step, int signo)DESCRIPTION	Resume execution of the inferior process.  If STEP is nozero, then	just single step it.  If SIGNAL is nonzero, restart it with that	signal activated.NOTE	It may not be absolutely necessary to specify the PC value for	restarting, but to be safe we use the value that gdb considers	to be current.  One case where this might be necessary is if the	user explicitly changes the PC value that gdb considers to be	current.  FIXME:  Investigate if this is necessary or not.	When attaching to a child process, if we forced it to stop with	a PIOCSTOP, then we will have set the nopass_next_sigstop flag.	Upon resuming the first time after such a stop, we explicitly	inhibit sending it another SIGSTOP, which would be the normal	result of default signal handling.  One potential drawback to	this is that we will also ignore any attempt to by the user	to explicitly continue after the attach with a SIGSTOP.  Ultimately	this problem should be dealt with by making the routines that	deal with the inferior a little smarter, and possibly even allow	an inferior to continue running at the same time as gdb.  (FIXME?) */static voidprocfs_resume (step, signo)     int step;     int signo;{  errno = 0;  pi.prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;#ifdef PRSVADDR_BROKEN/* Can't do this under Solaris running on a Sparc, as there seems to be no   place to put nPC.  In fact, if you use this, nPC seems to be set to some   random garbage.  We have to rely on the fact that PC and nPC have been   written previously via PIOCSREG during a register flush. */  pi.prrun.pr_vaddr = (caddr_t) *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];  pi.prrun.pr_flags != PRSVADDR;#endif  if (signo && !(signo == SIGSTOP && pi.nopass_next_sigstop))    {      set_proc_siginfo (&pi, signo);    }  else    {      pi.prrun.pr_flags |= PRCSIG;    }  pi.nopass_next_sigstop = 0;  if (step)    {      pi.prrun.pr_flags |= PRSTEP;    }  if (ioctl (pi.fd, PIOCRUN, &pi.prrun) != 0)    {      perror_with_name (pi.pathname);      /* NOTREACHED */    }}/*LOCAL FUNCTION	procfs_fetch_registers -- fetch current registers from inferiorSYNOPSIS	void procfs_fetch_registers (int regno)DESCRIPTION	Read the current values of the inferior's registers, both the	general register set and floating point registers (if supported)	and update gdb's idea of their current values.*/static voidprocfs_fetch_registers (regno)     int regno;{  if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)    {      supply_gregset (&pi.gregset);    }#if defined (FP0_REGNUM)  if (ioctl (pi.fd, PIOCGFPREG, &pi.fpregset) != -1)    {      supply_fpregset (&pi.fpregset);    }#endif}/*GLOBAL FUNCTION	fetch_core_registers -- fetch current registers from core file dataSYNOPSIS	void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,				   int which, unsigned in reg_addr)DESCRIPTION	Read the values of either the general register set (WHICH equals 0)	or the floating point register set (WHICH equals 2) from the core	file data (pointed to by CORE_REG_SECT), and update gdb's idea of	their current values.  The CORE_REG_SIZE parameter is ignored.NOTES	Use the indicated sizes to validate the gregset and fpregset	structures.*/voidfetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)     char *core_reg_sect;     unsigned core_reg_size;     int which;     unsigned int reg_addr;	/* Unused in this version */{  if (which == 0)    {      if (core_reg_size != sizeof (pi.gregset))	{	  warning ("wrong size gregset struct in core file");	}      else	{	  memcpy ((char *) &pi.gregset, core_reg_sect, sizeof (pi.gregset));	  supply_gregset (&pi.gregset);	}    }  else if (which == 2)    {      if (core_reg_size != sizeof (pi.fpregset))	{	  warning ("wrong size fpregset struct in core file");	}      else	{	  memcpy ((char *) &pi.fpregset, core_reg_sect, sizeof (pi.fpregset));#if defined (FP0_REGNUM)	  supply_fpregset (&pi.fpregset);#endif	}    }}/*LOCAL FUNCTION	proc_init_failed - called whenever /proc access initialization failsSYNOPSIS	static void proc_init_failed (char *why)DESCRIPTION	This function is called whenever initialization of access to a /proc	entry fails.  It prints a suitable error message, does some cleanup,	and then invokes the standard error processing routine which dumps	us back into the command loop. */static voidproc_init_failed (why)     char *why;{  print_sys_errmsg (pi.pathname, errno);  kill (pi.pid, SIGKILL);  close_proc_file (&pi);  error (why);  /* NOTREACHED */}/*LOCAL FUNCTION	close_proc_file - close any currently open /proc entrySYNOPSIS	static void close_proc_file (struct procinfo *pip)DESCRIPTION	Close any currently open /proc entry and mark the process information	entry as invalid.  In order to ensure that we don't try to reuse any	stale information, the pid, fd, and pathnames are explicitly	invalidated, which may be overkill. */static voidclose_proc_file (pip)     struct procinfo *pip;{  pip -> pid = 0;  if (pip -> valid)    {      close (pip -> fd);    }  pip -> fd = -1;  if (pip -> pathname)    {      free (pip -> pathname);      pip -> pathname = NULL;    }  pip -> valid = 0;}/*LOCAL FUNCTION	open_proc_file - open a /proc entry for a given process idSYNOPSIS	static int open_proc_file (int pid, struct procinfo *pip, int mode)DESCRIPTION	Given a process id and a mode, close the existing open /proc	entry (if any) and open one for the new process id, in the	specified mode.  Once it is open, then mark the local process	information structure as valid, which guarantees that the pid,	fd, and pathname fields match an open /proc entry.  Returns	zero if the open fails, nonzero otherwise.	Note that the pathname is left intact, even when the open fails,	so that callers can use it to construct meaningful error messages	rather than just "file open failed". */static intopen_proc_file (pid, pip, mode)     int pid;     struct procinfo *pip;     int mode;{  pip -> valid = 0;		/* FIXME, what is this? ?!  */  if (pip -> valid)    {      close (pip -> fd);    }  if (pip -> pathname == NULL)    {      pip -> pathname = xmalloc (32);    }  sprintf (pip -> pathname, PROC_NAME_FMT, pid);  if ((pip -> fd = open (pip -> pathname, mode)) >= 0)    {      pip -> valid = 1;      pip -> pid = pid;    }  return (pip -> valid);}static char *mappingflags (flags)     long flags;{  static char asciiflags[8];    strcpy (asciiflags, "-------");#if defined (MA_PHYS)  if (flags & MA_PHYS)   asciiflags[0] = 'd';#endif  if (flags & MA_STACK)  asciiflags[1] = 's';  if (flags & MA_BREAK)  asciiflags[2] = 'b';  if (flags & MA_SHARED) asciiflags[3] = 's';  if (flags & MA_READ)   asciiflags[4] = 'r';  if (flags & MA_WRITE)  asciiflags[5] = 'w';  if (flags & MA_EXEC)   asciiflags[6] = 'x';  return (asciiflags);}static voidinfo_proc_flags (pip, summary)     struct procinfo *pip;     int summary;{  struct trans *transp;  printf_filtered ("%-32s", "Process status flags:");  if (!summary)    {      printf_filtered ("\n\n");    }  for (transp = pr_flag_table; transp -> name != NULL; transp++)    {      if (pip -> prstatus.pr_flags & transp -> value)	{	  if (summary)	    {	      printf_filtered ("%s ", transp -> name);	    }	  else	    {	      printf_filtered ("\t%-16s %s.\n", transp -> name, transp -> desc);	    }	}    }  printf_filtered ("\n");}static voidinfo_proc_stop (pip, summary)     struct procinfo *pip;     int summary;{  struct trans *transp;  int why;  int what;  why = pip -> prstatus.pr_why;  what = pip -> prstatus.pr_what;  if (pip -> prstatus.pr_flags & PR_STOPPED)    {      printf_filtered ("%-32s", "Reason for stopping:");      if (!summary)	{	  printf_filtered ("\n\n");	}      for (transp = pr_why_table; transp -> name != NULL; transp++)	{	  if (why == transp -> value)	    {	      if (summary)		{		  printf_filtered ("%s ", transp -> name);		}	      else		{		  printf_filtered ("\t%-16s %s.\n",				   transp -> name, transp -> desc);		}	      break;	    }	}            /* Use the pr_why field to determine what the pr_what field means, and	 print more information. */            switch (why)	{	  case PR_REQUESTED:	    /* pr_what is unused for this case */	    break;	  case PR_JOBCONTROL:	  case PR_SIGNALLED:	    if (summary)	      {		printf_filtered ("%s ", signalname (what));	      }	    else	      {		printf_filtered ("\t%-16s %s.\n", signalname (what),				 safe_strsignal (what));	      }	    break;	  case PR_SYSENTRY:	    if (summary)	      {		printf_filtered ("%s ", syscallname (what));	      }	    else	      {		printf_filtered ("\t%-16s %s.\n", syscallname (what),				 "Entered this system call");	      }	    break;	  case PR_SYSEXIT:	    if (summary)	      {		printf_filtered ("%s ", syscallname (what));	      }	    else	      {		printf_filtered ("\t%-16s %s.\n", syscallname (what),				 "Returned from this system call");	      }	    break;	  case PR_FAULTED:	    if (summary)	      {		printf_filtered ("%s ",				 lookupname (faults_table, what, "fault"));	      }	    else	      {		printf_filtered ("\t%-16s %s.\n",				 lookupname (faults_table, what, "fault"),				 lookupdesc (faults_table, what));	      }	    break;	  }      printf_filtered ("\n");    }}static voidinfo_proc_siginfo (pip, summary)     struct procinfo *pip;     int summary;{  struct siginfo *sip;  if ((pip -> prstatus.pr_flags & PR_STOPPED) &&      (pip -> prstatus.pr_why == PR_SIGNALLED ||       pip -> prstatus.pr_why == PR_FAULTED))    {      printf_filtered ("%-32s", "Additional signal/fault info:");      sip = &pip -> prstatus.pr_info;      if (summary)	{	  printf_filtered ("%s ", signalname (sip -> si_signo));	  if (sip -> si_errno > 0)	    {	      printf_filtered ("%s ", errnoname (sip -> si_errno));	    }	  if (sip -> si_code <= 0)	    {	      printf_filtered ("sent by pid %d, uid %d ", sip -> si_pid,			       sip -> si_uid);	    }	  else	    {	      printf_filtered ("%s ", sigcodename (sip));	      if ((sip -> si_signo == SIGILL) ||		  (sip -> si_signo == SIGFPE) ||		  (sip -> si_signo == SIGSEGV) ||		  (sip -> si_signo == SIGBUS))		{		  printf_filtered ("addr=%#x ", sip -> si_addr);		}	      else if ((sip -> si_signo == SIGCHLD))		{		  printf_filtered ("child pid %u, status %u ",				   sip -> si_pid,				   sip -> si_status);		}	      else if ((sip -> si_signo == SIGPOLL))		{		  printf_filtered ("band %u ", sip -> si_band);		}	    }	}      else	{	  printf_filtered ("\n\n");	  printf_filtered ("\t%-16s %s.\n", signalname (sip -> si_signo),			   safe_strsignal (sip -> si_signo));	  if (sip -> si_errno > 0)	    {	      printf_filtered ("\t%-16s %s.\n",			       errnoname (sip -> si_errno),			       safe_strerror (sip -> si_errno));	    }	  if (sip -> si_code <= 0)	    {	      printf_filtered ("\t%-16u %s\n", sip -> si_pid,			       "PID of process sending signal");	      printf_filtered ("\t%-16u %s\n", sip -> si_uid,			       "UID of process sending signal");	    }	  else	    {	      printf_filtered ("\t%-16s %s.\n", sigcodename (sip),			       sigcodedesc (sip));	      if ((sip -> si_signo == SIGILL) ||		  (sip -> si_signo == SIGFPE))		{		  printf_filtered ("\t%-16#x %s.\n", sip -> si_addr,				   "Address of faulting instruction");		}	      else if ((sip -> si_signo == SIGSEGV) ||		       (sip -> si_signo == SIGBUS))		{		  printf_filtered ("\t%-16#x %s.\n", sip -> si_addr,				   "Address of faulting memory reference");		}	      else if ((sip -> si_signo == SIGCHLD))		{		  printf_filtered ("\t%-16u %s.\n", sip -> si_pid,				   "Child process ID");		  printf_filtered ("\t%-16u %s.\n", sip -> si_status,				   "Child process exit value or signal");		}	      else if ((sip -> si_signo == SIGPOLL))		{		  printf_filtered ("\t%-16u %s.\n", sip -> si_band,				   "Band event for POLL_{IN,OUT,MSG}");		}	    }	}      printf_filtered ("\n");    }}static voidinfo_proc_syscalls (pip, summary)     struct procinfo *pip;     int summary;{  int syscallnum;  if (!summary)    {#if 0	/* FIXME:  Needs to use gdb-wide configu

⌨️ 快捷键说明

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