Ejemplo n.º 1
0
/* This is a bit more fancy that need be so that it syncs even in nasty cases.

   I'be been unable to make it reliably sync up with the change
   baudrate open command.  It likes to sit and say it's been reset,
   with no more action.  So I took all that code out.  I'd rather sync
   reliably at 9600 than wait forever for a possible 19200 connection.

 */
static void
rdp_init (int cold, int tty)
{
  int sync = 0;
  int type = cold ? RDP_OPEN_TYPE_COLD : RDP_OPEN_TYPE_WARM;
  int baudtry = 9600;

  time_t now = time (0);
  time_t stop_time = now + 10;	/* Try and sync for 10 seconds, then give up */


  while (time (0) < stop_time && !sync)
    {
      int restype;
      QUIT;

      serial_flush_input (io);
      serial_flush_output (io);

      if (tty)
	printf_unfiltered ("Trying to connect at %d baud.\n", baudtry);

      /*
         ** It seems necessary to reset an EmbeddedICE to get it going.
         ** This has the side benefit of displaying the startup banner.
       */
      if (cold)
	{
	  put_byte (RDP_RESET);
	  while ((restype = serial_readchar (io, 1)) > 0)
	    {
	      switch (restype)
		{
		case SERIAL_TIMEOUT:
		  break;
		case RDP_RESET:
		  /* Sent at start of reset process: ignore */
		  break;
		default:
		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
		  break;
		}
	    }

	  if (restype == 0)
	    {
	      /* Got end-of-banner mark */
	      printf_filtered ("\n");
	    }
	}

      put_byte (RDP_OPEN);

      put_byte (type | RDP_OPEN_TYPE_RETURN_SEX);
      put_word (0);

      while (!sync && (restype = serial_readchar (io, 1)) > 0)
	{
	  if (remote_debug)
	    fprintf_unfiltered (gdb_stdlog, "[%02x]\n", restype);

	  switch (restype)
	    {
	    case SERIAL_TIMEOUT:
	      break;

	    case RDP_RESET:
	      while ((restype = serial_readchar (io, 1)) == RDP_RESET)
		;
	      do
		{
		  printf_unfiltered ("%c", isgraph (restype) ? restype : ' ');
		}
	      while ((restype = serial_readchar (io, 1)) > 0);

	      if (tty)
		{
		  printf_unfiltered ("\nThe board has sent notification that it was reset.\n");
		  printf_unfiltered ("Waiting for it to settle down...\n");
		}
	      sleep (3);
	      if (tty)
		printf_unfiltered ("\nTrying again.\n");
	      cold = 0;
	      break;

	    default:
	      break;

	    case RDP_RES_VALUE:
	      {
		int resval = serial_readchar (io, 1);

		if (remote_debug)
		  fprintf_unfiltered (gdb_stdlog, "[%02x]\n", resval);

		switch (resval)
		  {
		  case SERIAL_TIMEOUT:
		    break;
		  case RDP_RES_VALUE_LITTLE_ENDIAN:
#if 0
		    /* FIXME: cagney/2003-11-22: Ever since the ARM
                       was multi-arched (in 2002-02-08), this
                       assignment has had no effect.  There needs to
                       be some sort of check/decision based on the
                       current architecture's byte-order vs the remote
                       target's byte order.  For the moment disable
                       the assignment to keep things building.  */
		    target_byte_order = BFD_ENDIAN_LITTLE;
#endif
		    sync = 1;
		    break;
		  case RDP_RES_VALUE_BIG_ENDIAN:
#if 0
		    /* FIXME: cagney/2003-11-22: Ever since the ARM
                       was multi-arched (in 2002-02-08), this
                       assignment has had no effect.  There needs to
                       be some sort of check/decision based on the
                       current architecture's byte-order vs the remote
                       target's byte order.  For the moment disable
                       the assignment to keep things building.  */
		    target_byte_order = BFD_ENDIAN_BIG;
#endif
		    sync = 1;
		    break;
		  default:
		    break;
		  }
	      }
	    }
	}
    }

  if (!sync)
    {
      error ("Couldn't reset the board, try pressing the reset button");
    }
}
Ejemplo n.º 2
0
/* APPLE LOCAL BEGIN: segment binary file download: */
static void
restore_binary_file(char *filename, struct callback_data *data)
{
  FILE *file = fopen_with_cleanup(filename, FOPEN_RB);
  gdb_byte *buf;
  long len;
  long total_file_bytes;
  long bytes_to_read_from_file;

  CORE_ADDR addrp;

  /* Get the file size for reading: */
  if (fseek(file, 0L, SEEK_END) == 0)
    total_file_bytes = ftell(file);
  else
    perror_with_name(filename);

  if (total_file_bytes <= (int)data->load_start)
    error(_("Start address is greater than length of binary file %s."),
          filename);

  bytes_to_read_from_file = (int)data->load_end;
  if (bytes_to_read_from_file == 0)
    bytes_to_read_from_file = total_file_bytes;
  if (data->load_start > 0)
    bytes_to_read_from_file -= (int)data->load_start;

  if (bytes_to_read_from_file > total_file_bytes)
    bytes_to_read_from_file = total_file_bytes;

  printf_filtered("Restoring binary file %s into memory (0x%s to 0x%s)\n",
                  filename,
                  paddr_nz(data->load_start + data->load_offset),
                  paddr_nz(data->load_start + data->load_offset + bytes_to_read_from_file));

  /* Now set the file pos to the requested load start pos: */
  if (fseek(file, (long)data->load_start, SEEK_SET) != 0)
    perror_with_name(filename);

  if (bytes_to_read_from_file > g_max_binary_file_chunk)
    len = g_max_binary_file_chunk;
  else
    len = bytes_to_read_from_file;

  buf = (gdb_byte *)xmalloc(len);
  make_cleanup(xfree, buf);

  addrp = (data->load_start + data->load_offset);
  /* BYTES_TO_READ_FROM_FILE decreases each time through this loop;
     we read g_max_binary_file_chunk or less bytes at each iteration.  */
  while (bytes_to_read_from_file > 0)
    {
      int max_errors;

      /* The last chunk we shall be reading -- at this point our LEN buffer
         is larger than the remaining number of bytes to be read; cap it
         so we do NOT read off the end of the file. */
      if (len > bytes_to_read_from_file)
        len = bytes_to_read_from_file;

      if (fread(buf, 1, len, file) != (size_t)len)
	perror_with_name(filename);

      max_errors = 2;
      while (max_errors > 0)
        {
           printf_unfiltered(_("Writing 0x%s bytes to 0x%s\n"), paddr_nz(len),
			     paddr_nz(addrp));
           gdb_flush (gdb_stdout);
           if (target_write_memory(addrp, buf, (int)len) == 0)
             {
               addrp += len;
               break;
             }
           else
             {
	       warning(_("restore: memory write failed - retrying."));
               max_errors--;
             }
        }
      if (max_errors == 0)
        error ("restore: memory write failed.");

      bytes_to_read_from_file -= len;
    }
}
Ejemplo n.º 3
0
static void
fbsd_thread_resume (struct target_ops *ops,
		    ptid_t ptid, int step, enum target_signal signo)
{
  struct target_ops *beneath = find_target_beneath (ops);
  td_thrhandle_t th;
  td_thrinfo_t ti;
  ptid_t work_ptid;
  int resume_all, ret;
  long lwp, thvalid = 0;

  if (!fbsd_thread_active)
    {
      // XXX: I don't think this can happen
      printf_unfiltered ("%s: called without active threads\n", __func__);
      beneath->to_resume (beneath, ptid, step, signo);
      return;
    }

  if (GET_PID(ptid) != -1 && step != 0)
    {
      resume_all = 0;
      work_ptid = ptid;
    }
  else
    {
      resume_all = 1;
      work_ptid = inferior_ptid;
    }

  lwp = GET_LWP (work_ptid);
  if (lwp == 0)
    {
      /* check user thread */
      ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(work_ptid), &th);
      if (ret)
        error ("%s: %s", __func__, thread_db_err_str (ret));

      /* For M:N thread, we need to tell UTS to set/unset single step
         flag at context switch time, the flag will be written into
         thread mailbox. This becauses some architecture may not have
         machine single step flag in ucontext, so we put the flag in mailbox,
         when the thread switches back, kse_switchin restores the single step
         state.  */
      ret = td_thr_sstep_p (&th, step);
      if (ret)
        error ("%s: %s", __func__, thread_db_err_str (ret));
      ret = td_thr_get_info_p (&th, &ti);
      if (ret)
        error ("%s: %s", __func__, thread_db_err_str (ret));
      thvalid = 1;
      lwp = ti.ti_lid;
    }

  if (lwp)
    {
      int req = step ? PT_SETSTEP : PT_CLEARSTEP;
      if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
        perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
    }

  if (!ptid_equal (last_single_step_thread, null_ptid))
    {
       ret = td_ta_thr_iter_p (thread_agent, resume_thread_callback, NULL,
          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
      if (ret != TD_OK)
        error ("resume error: %s", thread_db_err_str (ret));
    }

  if (!resume_all)
    {
      ret = td_ta_thr_iter_p (thread_agent, suspend_thread_callback, NULL,
          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
      if (ret != TD_OK)
        error ("suspend error: %s", thread_db_err_str (ret));
      last_single_step_thread = work_ptid;
    }
  else
    last_single_step_thread = null_ptid;

  if (thvalid)
    {
      ret = td_thr_dbresume_p (&th);
      if (ret != TD_OK)
        error ("resume error: %s", thread_db_err_str (ret));
    }
  else
    {
      /* it is not necessary, put it here for completness */
      ret = ptrace(PT_RESUME, lwp, 0, 0);
    }

  /* now continue the process, suspended thread wont run */
  if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
	      target_signal_to_host(signo)))
    perror_with_name ("PT_CONTINUE");
}
Ejemplo n.º 4
0
static void
haiku_child_close (int x)
{
	printf_unfiltered ("gdb: child_close, inferior_ptid=%d\n",
		PIDGET (inferior_ptid));
}
Ejemplo n.º 5
0
void
exec_file_attach (char *filename, int from_tty)
{
  struct cleanup *cleanups;

  /* First, acquire a reference to the current exec_bfd.  We release
     this at the end of the function; but acquiring it now lets the
     BFD cache return it if this call refers to the same file.  */
  gdb_bfd_ref (exec_bfd);
  cleanups = make_cleanup_bfd_unref (exec_bfd);

  /* Remove any previous exec file.  */
  exec_close ();

  /* Now open and digest the file the user requested, if any.  */

  if (!filename)
    {
      if (from_tty)
        printf_unfiltered (_("No executable file now.\n"));

      set_gdbarch_from_file (NULL);
    }
  else
    {
      char *scratch_pathname, *canonical_pathname;
      int scratch_chan;
      struct target_section *sections = NULL, *sections_end = NULL;
      char **matching;

      scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename,
		   write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
			    &scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
      if (scratch_chan < 0)
	{
	  char *exename = alloca (strlen (filename) + 5);

	  strcat (strcpy (exename, filename), ".exe");
	  scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
	     write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
	     &scratch_pathname);
	}
#endif
      if (scratch_chan < 0)
	perror_with_name (filename);

      make_cleanup (xfree, scratch_pathname);

      /* gdb_bfd_open (and its variants) prefers canonicalized pathname for
	 better BFD caching.  */
      canonical_pathname = gdb_realpath (scratch_pathname);
      make_cleanup (xfree, canonical_pathname);

      if (write_files)
	exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
				  FOPEN_RUB, scratch_chan);
      else
	exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);

      if (!exec_bfd)
	{
	  error (_("\"%s\": could not open as an executable file: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      gdb_assert (exec_filename == NULL);
      exec_filename = gdb_realpath_keepfile (scratch_pathname);

      if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": not in executable format: %s"),
		 scratch_pathname,
		 gdb_bfd_errmsg (bfd_get_error (), matching));
	}

      if (build_section_table (exec_bfd, &sections, &sections_end))
	{
	  /* Make sure to close exec_bfd, or else "run" might try to use
	     it.  */
	  exec_close ();
	  error (_("\"%s\": can't find the file sections: %s"),
		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
	}

      exec_bfd_mtime = bfd_get_mtime (exec_bfd);

      validate_files ();

      set_gdbarch_from_file (exec_bfd);

      /* Add the executable's sections to the current address spaces'
	 list of sections.  This possibly pushes the exec_ops
	 target.  */
      add_target_sections (&exec_bfd, sections, sections_end);
      xfree (sections);

      /* Tell display code (if any) about the changed file name.  */
      if (deprecated_exec_file_display_hook)
	(*deprecated_exec_file_display_hook) (filename);
    }

  do_cleanups (cleanups);

  bfd_cache_close_all ();
  observer_notify_executable_changed ();
}
Ejemplo n.º 6
0
static void
record_btrace_call_history (int size, int flags)
{
  struct btrace_thread_info *btinfo;
  struct cleanup *uiout_cleanup;
  struct ui_out *uiout;
  unsigned int context, last, begin, end;

  uiout = current_uiout;
  uiout_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout,
						       "insn history");
  btinfo = require_btrace ();
  last = VEC_length (btrace_func_s, btinfo->ftrace);

  context = abs (size);
  begin = btinfo->func_iterator.begin;
  end = btinfo->func_iterator.end;

  DEBUG ("func-history (0x%x): %d, prev: [%u; %u[", flags, size, begin, end);

  if (context == 0)
    error (_("Bad record function-call-history-size."));

  /* We start at the end.  */
  if (end < begin)
    {
      /* Truncate the context, if necessary.  */
      context = min (context, last);

      end = last;
      begin = end - context;
    }
  else if (size < 0)
    {
      if (begin == 0)
	{
	  printf_unfiltered (_("At the start of the branch trace record.\n"));

	  btinfo->func_iterator.end = 0;
	  return;
	}

      /* Truncate the context, if necessary.  */
      context = min (context, begin);

      end = begin;
      begin -= context;
    }
  else
    {
      if (end == last)
	{
	  printf_unfiltered (_("At the end of the branch trace record.\n"));

	  btinfo->func_iterator.begin = last;
	  return;
	}

      /* Truncate the context, if necessary.  */
      context = min (context, last - end);

      begin = end;
      end += context;
    }

  btrace_func_history (btinfo, uiout, begin, end, flags);

  btinfo->func_iterator.begin = begin;
  btinfo->func_iterator.end = end;

  do_cleanups (uiout_cleanup);
}
Ejemplo n.º 7
0
static ptid_t
haiku_child_wait_internal (team_debug_info *teamDebugInfo, ptid_t ptid,
	struct target_waitstatus *ourstatus, bool *ignore, bool *selectThread)
{
	team_id teamID = ptid_get_pid(ptid);
	team_id threadID = ptid_get_tid(ptid);
	debug_event *event = NULL;
	ptid_t retval = pid_to_ptid(-1);
	struct thread_debug_info *thread;
	int pendingSignal = -1;
	pending_signal_status pendingSignalStatus = SIGNAL_FAKED;
	int reprocessEvent = -1;

	*selectThread = false;

	if (teamID < 0 || threadID == 0)
		threadID = -1;

	// if we're waiting for any thread, search the thread list for already
	// stopped threads (needed for reprocessing events)
	if (threadID < 0) {
		for (thread = teamDebugInfo->threads; thread; thread = thread->next) {
			if (thread->stopped) {
				threadID = thread->thread;
				break;
			}
		}
	}

	// check, if the thread exists and is already stopped
	if (threadID >= 0
		&& (thread = haiku_find_thread(teamDebugInfo, threadID)) != NULL
		&& thread->stopped) {
		// remove the event that stopped the thread from the thread (we will
		// add it again, if it shall not be ignored)
		event = thread->last_event;
		thread->last_event = NULL;
		thread->stopped = false;
		reprocessEvent = thread->reprocess_event;

		TRACE(("haiku_child_wait_internal(): thread %ld already stopped. "
			"re-digesting the last event (%p).\n", threadID, event));
	} else {
		// prepare closure for finding interesting events
		thread_event_closure threadEventClosure;
		threadEventClosure.context = teamDebugInfo;
		threadEventClosure.thread = threadID;
		threadEventClosure.event = NULL;

		// find the first interesting queued event
		threadEventClosure.event = haiku_find_next_debug_event(
			&teamDebugInfo->events, haiku_thread_event_predicate,
			&threadEventClosure);

		// read all events pending on the port
		haiku_read_pending_debug_events(teamDebugInfo,
			(threadEventClosure.event == NULL), haiku_thread_event_predicate,
			&threadEventClosure);

		// get the event of interest
		event = haiku_remove_debug_event(&teamDebugInfo->events,
			threadEventClosure.event);

		if (!event) {
			TRACE(("haiku_child_wait_internal(): got no event!\n"));
			return retval;
		}

		TRACE(("haiku_child_wait_internal(): got event: %u, thread: %ld, "
			"team: %ld, nub port: %ld\n", event->message,
			event->data.origin.thread, event->data.origin.team,
			event->data.origin.nub_port));
	}

	if (event->data.origin.team != teamDebugInfo->team) {
		// Spurious debug message. Doesn't concern our team. Ignore.
		xfree(event);
		return retval;
	}

	retval = ptid_build(event->data.origin.team, 0, event->data.origin.thread);

	*ignore = false;

	switch (event->message) {
		case B_DEBUGGER_MESSAGE_DEBUGGER_CALL:
		{
			// print the debugger message
			char debuggerMessage[1024];
			ssize_t bytesRead = debug_read_string(&teamDebugInfo->context,
				event->data.debugger_call.message, debuggerMessage,
				sizeof(debuggerMessage));
			if (bytesRead > 0) {
				printf_unfiltered ("Thread %ld called debugger(): %s\n",
					event->data.origin.thread, debuggerMessage);
			} else {
				printf_unfiltered ("Thread %ld called debugger(), but failed"
					"to get the debugger message.\n",
					event->data.origin.thread);
			}

			// fall through...
		}
		case B_DEBUGGER_MESSAGE_THREAD_DEBUGGED:
		case B_DEBUGGER_MESSAGE_BREAKPOINT_HIT:
		case B_DEBUGGER_MESSAGE_WATCHPOINT_HIT:
		case B_DEBUGGER_MESSAGE_SINGLE_STEP:
			ourstatus->kind = TARGET_WAITKIND_STOPPED;
			ourstatus->value.sig = TARGET_SIGNAL_TRAP;
			pendingSignal = SIGTRAP;
			pendingSignalStatus = SIGNAL_FAKED;
			break;

		case B_DEBUGGER_MESSAGE_PRE_SYSCALL:
			ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY;
			ourstatus->value.syscall_id = event->data.pre_syscall.syscall;
			break;

		case B_DEBUGGER_MESSAGE_POST_SYSCALL:
			ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN;
			ourstatus->value.syscall_id = event->data.post_syscall.syscall;
			break;

		case B_DEBUGGER_MESSAGE_SIGNAL_RECEIVED:
			pendingSignal = event->data.signal_received.signal;
			pendingSignalStatus = SIGNAL_ARRIVED;
			ourstatus->kind = TARGET_WAITKIND_STOPPED;
			ourstatus->value.sig = haiku_to_target_signal(pendingSignal);
			break;

		case B_DEBUGGER_MESSAGE_EXCEPTION_OCCURRED:
		{
			// print the exception message
			char exception[1024];
			get_debug_exception_string(event->data.exception_occurred.exception,
				exception, sizeof(exception));
			printf_unfiltered ("Thread %ld caused an exception: %s\n",
				event->data.origin.thread, exception);

			pendingSignal = event->data.exception_occurred.signal;
			pendingSignalStatus = SIGNAL_WILL_ARRIVE;
			ourstatus->kind = TARGET_WAITKIND_STOPPED;
			ourstatus->value.sig = haiku_to_target_signal(pendingSignal);
			break;
		}

		case B_DEBUGGER_MESSAGE_TEAM_CREATED:
			// ignore
			*ignore = true;
			break;

		case B_DEBUGGER_MESSAGE_TEAM_DELETED:
			ourstatus->kind = TARGET_WAITKIND_EXITED;
			ourstatus->value.integer = 0;
				// TODO: Extend the debugger interface?
			break;

		case B_DEBUGGER_MESSAGE_THREAD_CREATED:
		{
			// internal bookkeeping only
			thread_id newThread = event->data.thread_created.new_thread;
			if (newThread != teamDebugInfo->nub_thread)
				haiku_add_thread(teamDebugInfo, newThread);
			*ignore = true;
			break;
		}

		case B_DEBUGGER_MESSAGE_THREAD_DELETED:
			// internal bookkeeping
			haiku_remove_thread(teamDebugInfo,
				event->data.thread_deleted.origin.thread);
			*ignore = true;

			// TODO: What if this is the current thread?
			break;

		case B_DEBUGGER_MESSAGE_IMAGE_CREATED:
			if (reprocessEvent < 0) {
				// first time we see the event: update our image list
//				haiku_add_image(teamDebugInfo,
//					&event->data.image_created.info);
haiku_cleanup_image_list(teamDebugInfo);
haiku_init_image_list(teamDebugInfo);
// TODO: We don't get events when images have been removed in preparation of
// an exec*() yet.
			}

			ourstatus->kind = TARGET_WAITKIND_LOADED;
			ourstatus->value.integer = 0;
			if (event->data.image_created.info.type == B_APP_IMAGE) {
				// An app image has been loaded, i.e. the application is now
				// fully loaded. We need to send a TARGET_WAITKIND_LOADED
				// first, so that GDB's shared object list is updated correctly.
				// But we also need to send an TARGET_WAITKIND_EXECD event.
				// We use the reprocessEvent mechanism here.

				if (reprocessEvent == 2) {
					// the second time the event is processed: send the `exec'
					// event
					if (inferior_ignoring_startup_exec_events > 0) {
						// we shall not send an exec event, so we skip that
						// and send the `trap' immediately
TRACE(("haiku_child_wait_internal(): ignoring exec (%d)\n",
inferior_ignoring_startup_exec_events));
						inferior_ignoring_startup_exec_events--;
						reprocessEvent = 1;
					}
				}

				if (reprocessEvent < 0) {
TRACE(("haiku_child_wait_internal(): B_APP_IMAGE created, reprocess < 0\n"));
					// the first time the event is processed: send the
					// `loaded' event
					reprocessEvent = 2;
				} else if (reprocessEvent == 2) {
TRACE(("haiku_child_wait_internal(): B_APP_IMAGE created, reprocess -> exec\n"));
					// the second time the event is processed: send the `exec'
					// event
					ourstatus->kind = TARGET_WAITKIND_EXECD;
					ourstatus->value.execd_pathname
						= event->data.image_created.info.name;

					reprocessEvent = 1;
				} else if (reprocessEvent <= 1) {
					// the third time the event is processed: send the `trap'
					// event
					ourstatus->kind = TARGET_WAITKIND_STOPPED;
					ourstatus->value.sig = TARGET_SIGNAL_TRAP;
					pendingSignal = SIGTRAP;
					pendingSignalStatus = SIGNAL_FAKED;

					reprocessEvent = 0;
				}
			}

			// re_enable_breakpoints_in_shlibs ();
				// TODO: Needed?
			break;

		case B_DEBUGGER_MESSAGE_IMAGE_DELETED:
			haiku_remove_image(teamDebugInfo,
				event->data.image_deleted.info.id);

			// send TARGET_WAITKIND_LOADED here too, it causes the shared
			// object list to be updated
			ourstatus->kind = TARGET_WAITKIND_LOADED;
			ourstatus->value.integer = 0;
			break;

		case B_DEBUGGER_MESSAGE_HANDED_OVER:
		{
TRACE(("haiku_child_wait_internal(): B_DEBUGGER_MESSAGE_HANDED_OVER: causing "
"thread: %ld\n", event->data.handed_over.causing_thread));
			// The debugged team has been handed over to us by another debugger
			// (likely the debug server). This event also tells us, which
			// thread has caused the original debugger to be installed (if any).
			// So, if we're not looking for any particular thread, select that
			// thread.
			if (threadID < 0 && event->data.handed_over.causing_thread >= 0) {
				*selectThread = true;
				retval = ptid_build(event->data.origin.team, 0,
					event->data.handed_over.causing_thread);
			}
			*ignore = true;
		}

		default:
			// unknown message, ignore
			*ignore = true;
			break;
	}

	// make the event the thread's last event or delete it
	if (!*ignore && event->data.origin.thread >= 0) {
		struct thread_debug_info *thread = haiku_find_thread(teamDebugInfo,
			event->data.origin.thread);
		if (thread->last_event)
			xfree(thread->last_event);
			thread->last_event = event;
			thread->stopped = true;
			thread->signal = pendingSignal;
			thread->signal_status = pendingSignalStatus;
			thread->reprocess_event
				= (reprocessEvent >= 0 ? reprocessEvent : 0);
	} else {
		xfree(event);

		// continue the thread
		if (event->data.origin.thread >= 0) {
			haiku_continue_thread(teamDebugInfo, event->data.origin.thread,
				B_THREAD_DEBUG_HANDLE_EVENT, false);
		}

//		*ignore = true;
// TODO: This should indeed not be needed. It definitely eats the
// `team deleted' events.
	}

	return retval;
}
Ejemplo n.º 8
0
Archivo: serial.c Proyecto: 0mp/freebsd
static void
connect_command (char *args, int fromtty)
{
  int c;
  char cur_esc = 0;
  serial_ttystate ttystate;
  struct serial *port_desc;		/* TTY port */

  dont_repeat ();

  if (args)
    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");

  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");

  tty_desc = serial_fdopen (0);
  port_desc = last_serial_opened;

  ttystate = serial_get_tty_state (tty_desc);

  serial_raw (tty_desc);
  serial_raw (port_desc);

  make_cleanup (cleanup_tty, ttystate);

  while (1)
    {
      int mask;

      mask = serial_wait_2 (tty_desc, port_desc, -1);

      if (mask & 2)
	{			/* tty input */
	  char cx;

	  while (1)
	    {
	      c = serial_readchar (tty_desc, 0);

	      if (c == SERIAL_TIMEOUT)
		break;

	      if (c < 0)
		perror_with_name ("connect");

	      cx = c;
	      serial_write (port_desc, &cx, 1);

	      switch (cur_esc)
		{
		case 0:
		  if (c == '\r')
		    cur_esc = c;
		  break;
		case '\r':
		  if (c == '~')
		    cur_esc = c;
		  else
		    cur_esc = 0;
		  break;
		case '~':
		  if (c == '.' || c == '\004')
		    return;
		  else
		    cur_esc = 0;
		}
	    }
	}

      if (mask & 1)
	{			/* Port input */
	  char cx;

	  while (1)
	    {
	      c = serial_readchar (port_desc, 0);

	      if (c == SERIAL_TIMEOUT)
		break;

	      if (c < 0)
		perror_with_name ("connect");

	      cx = c;

	      serial_write (tty_desc, &cx, 1);
	    }
	}
    }
}
Ejemplo n.º 9
0
Archivo: serial.c Proyecto: 0mp/freebsd
static void
serial_set_cmd (char *args, int from_tty)
{
  printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
  help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
}
Ejemplo n.º 10
0
/* Handle the given event by calling the procedure associated to the
   corresponding file handler.  Called by process_event indirectly,
   through event_ptr->proc.  EVENT_FILE_DESC is file descriptor of the
   event in the front of the event queue. */
static void
handle_file_event (int event_file_desc)
{
  file_handler *file_ptr;
  int mask;
#ifdef HAVE_POLL
  int error_mask;
  int error_mask_returned;
#endif

  /* Search the file handler list to find one that matches the fd in
     the event. */
  for (file_ptr = gdb_notifier.first_file_handler; file_ptr != NULL;
       file_ptr = file_ptr->next_file)
    {
      if (file_ptr->fd == event_file_desc)
	{
	  /* With poll, the ready_mask could have any of three events
	     set to 1: POLLHUP, POLLERR, POLLNVAL. These events cannot
	     be used in the requested event mask (events), but they
	     can be returned in the return mask (revents). We need to
	     check for those event too, and add them to the mask which
	     will be passed to the handler. */

	  /* See if the desired events (mask) match the received
	     events (ready_mask). */

	  if (use_poll)
	    {
#ifdef HAVE_POLL
	      error_mask = POLLHUP | POLLERR | POLLNVAL;
	      mask = (file_ptr->ready_mask & file_ptr->mask) |
		(file_ptr->ready_mask & error_mask);
	      error_mask_returned = mask & error_mask;

	      if (error_mask_returned != 0)
		{
		  /* Work in progress. We may need to tell somebody what
		     kind of error we had. */
		  if (error_mask_returned & POLLHUP)
		    printf_unfiltered (_("Hangup detected on fd %d\n"), file_ptr->fd);
		  if (error_mask_returned & POLLERR)
		    printf_unfiltered (_("Error detected on fd %d\n"), file_ptr->fd);
		  if (error_mask_returned & POLLNVAL)
		    printf_unfiltered (_("Invalid or non-`poll'able fd %d\n"), file_ptr->fd);
		  file_ptr->error = 1;
		}
	      else
		file_ptr->error = 0;
#else
	      internal_error (__FILE__, __LINE__,
			      _("use_poll without HAVE_POLL"));
#endif /* HAVE_POLL */
	    }
	  else
	    {
	      if (file_ptr->ready_mask & GDB_EXCEPTION)
		{
		  printf_unfiltered (_("Exception condition detected on fd %d\n"), file_ptr->fd);
		  file_ptr->error = 1;
		}
	      else
		file_ptr->error = 0;
	      mask = file_ptr->ready_mask & file_ptr->mask;
	    }

	  /* Clear the received events for next time around. */
	  file_ptr->ready_mask = 0;

	  /* If there was a match, then call the handler. */
	  if (mask != 0)
	    (*file_ptr->proc) (file_ptr->error, file_ptr->client_data);
	  break;
	}
    }
}
Ejemplo n.º 11
0
static void
i386_darwin_dr_set (int regnum, uint32_t value)
{
  int current_pid;
  thread_t current_thread;
  x86_debug_state_t dr_regs;
  kern_return_t ret;
  unsigned int dr_count = x86_DEBUG_STATE_COUNT;

  gdb_assert (regnum >= 0 && regnum <= DR_CONTROL);

  current_thread = ptid_get_tid (inferior_ptid);

  dr_regs.dsh.flavor = x86_DEBUG_STATE32;
  dr_regs.dsh.count = x86_DEBUG_STATE32_COUNT;
  dr_count = x86_DEBUG_STATE_COUNT;
  ret = thread_get_state (current_thread, x86_DEBUG_STATE, 
                          (thread_state_t) &dr_regs, &dr_count);

  if (ret != KERN_SUCCESS)
    {
      printf_unfiltered (_("Error reading debug registers "
			   "thread 0x%x via thread_get_state\n"),
			 (int) current_thread);
      MACH_CHECK_ERROR (ret);
    }

  switch (regnum) 
    {
      case 0:
        dr_regs.uds.ds32.__dr0 = value;
        break;
      case 1:
        dr_regs.uds.ds32.__dr1 = value;
        break;
      case 2:
        dr_regs.uds.ds32.__dr2 = value;
        break;
      case 3:
        dr_regs.uds.ds32.__dr3 = value;
        break;
      case 4:
        dr_regs.uds.ds32.__dr4 = value;
        break;
      case 5:
        dr_regs.uds.ds32.__dr5 = value;
        break;
      case 6:
        dr_regs.uds.ds32.__dr6 = value;
        break;
      case 7:
        dr_regs.uds.ds32.__dr7 = value;
        break;
    }

  ret = thread_set_state (current_thread, x86_DEBUG_STATE, 
                          (thread_state_t) &dr_regs, dr_count);

  if (ret != KERN_SUCCESS)
    {
      printf_unfiltered (_("Error writing debug registers "
			   "thread 0x%x via thread_get_state\n"),
			 (int) current_thread);
      MACH_CHECK_ERROR (ret);
    }
}
Ejemplo n.º 12
0
/* General function to handle events in the inferior.  So far it just
   takes care of detecting errors reported by select() or poll(),
   otherwise it assumes that all is OK, and goes on reading data from
   the fd.  This however may not always be what we want to do.  */
void
inferior_event_handler (enum inferior_event_type event_type, 
			gdb_client_data client_data)
{
  struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();

  switch (event_type)
    {
    case INF_REG_EVENT:
      /* Use catch errors for now, until the inner layers of
	 fetch_inferior_event (i.e. readchar) can return meaningful
	 error status.  If an error occurs while getting an event from
	 the target, just cancel the current command.  */
      if (!catch_errors (fetch_inferior_event_wrapper, 
			 client_data, "", RETURN_MASK_ALL))
	{
	  bpstat_clear_actions ();
	  do_all_intermediate_continuations (1);
	  do_all_continuations (1);
	  async_enable_stdin ();
	  observer_notify_command_error ();
	}
      break;

    case INF_EXEC_COMPLETE:
      if (!non_stop)
	{
	  /* Unregister the inferior from the event loop.  This is done
	     so that when the inferior is not running we don't get
	     distracted by spurious inferior output.  */
	  if (target_has_execution)
	    target_async (NULL, 0);
	}

      /* Do all continuations associated with the whole inferior (not
	 a particular thread).  */
      if (!ptid_equal (inferior_ptid, null_ptid))
	do_all_inferior_continuations (0);

      /* If we were doing a multi-step (eg: step n, next n), but it
	 got interrupted by a breakpoint, still do the pending
	 continuations.  The continuation itself is responsible for
	 distinguishing the cases.  The continuations are allowed to
	 touch the inferior memory, e.g. to remove breakpoints, so run
	 them before running breakpoint commands, which may resume the
	 target.  */
      if (non_stop
	  && target_has_execution
	  && !ptid_equal (inferior_ptid, null_ptid))
	do_all_intermediate_continuations_thread (inferior_thread (), 0);
      else
	do_all_intermediate_continuations (0);

      /* Always finish the previous command before running any
	 breakpoint commands.  Any stop cancels the previous command.
	 E.g. a "finish" or "step-n" command interrupted by an
	 unrelated breakpoint is canceled.  */
      if (non_stop
	  && target_has_execution
	  && !ptid_equal (inferior_ptid, null_ptid))
	do_all_continuations_thread (inferior_thread (), 0);
      else
	do_all_continuations (0);

      /* When running a command list (from a user command, say), these
	 are only run when the command list is all done.  */
      if (interpreter_async)
	{
	  volatile struct gdb_exception e;

	  check_frame_language_change ();

	  /* Don't propagate breakpoint commands errors.  Either we're
	     stopping or some command resumes the inferior.  The user will
	     be informed.  */
	  TRY_CATCH (e, RETURN_MASK_ALL)
	    {
	      bpstat_do_actions ();
	    }
	  exception_print (gdb_stderr, e);
	}
      break;

    case INF_EXEC_CONTINUE:
      /* Is there anything left to do for the command issued to
         complete?  */

      if (non_stop)
	do_all_intermediate_continuations_thread (inferior_thread (), 0);
      else
	do_all_intermediate_continuations (0);
      break;

    case INF_TIMER:
    default:
      printf_unfiltered (_("Event type not recognized.\n"));
      break;
    }

  discard_cleanups (cleanup_if_error);
}
Ejemplo n.º 13
0
Archivo: exec.c Proyecto: asdlei00/gdb
void
exec_file_attach (char *filename, int from_tty)
{
    /* Remove any previous exec file.  */
    exec_close ();

    /* Now open and digest the file the user requested, if any.  */

    if (!filename)
    {
        if (from_tty)
            printf_unfiltered (_("No executable file now.\n"));

        set_gdbarch_from_file (NULL);
    }
    else
    {
        struct cleanup *cleanups;
        char *scratch_pathname, *canonical_pathname;
        int scratch_chan;
        struct target_section *sections = NULL, *sections_end = NULL;
        char **matching;

        scratch_chan = openp (getenv ("PATH"),
                              OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH, filename,
                              write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
                              &scratch_pathname);
#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__)
        if (scratch_chan < 0)
        {
            char *exename = alloca (strlen (filename) + 5);

            strcat (strcpy (exename, filename), ".exe");
            scratch_chan = openp (getenv ("PATH"),
                                  OPF_TRY_CWD_FIRST | OPF_DISABLE_REALPATH,
                                  exename,
                                  write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY,
                                  &scratch_pathname);
        }
#endif
        if (scratch_chan < 0)
            perror_with_name (filename);

        cleanups = make_cleanup (xfree, scratch_pathname);

        /* gdb_bfd_open (and its variants) prefers canonicalized pathname for
        better BFD caching.  */
        canonical_pathname = gdb_realpath (scratch_pathname);
        make_cleanup (xfree, canonical_pathname);

        if (write_files)
            exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget,
                                      FOPEN_RUB, scratch_chan);
        else
            exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan);

        if (!exec_bfd)
        {
            error (_("\"%s\": could not open as an executable file: %s"),
                   scratch_pathname, bfd_errmsg (bfd_get_error ()));
        }

        gdb_assert (exec_filename == NULL);
        exec_filename = xstrdup (scratch_pathname);

        if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching))
        {
            /* Make sure to close exec_bfd, or else "run" might try to use
               it.  */
            exec_close ();
            error (_("\"%s\": not in executable format: %s"),
                   scratch_pathname,
                   gdb_bfd_errmsg (bfd_get_error (), matching));
        }

        /* FIXME - This should only be run for RS6000, but the ifdef is a poor
           way to accomplish.  */
#ifdef DEPRECATED_IBM6000_TARGET
        /* Setup initial vmap.  */

        map_vmap (exec_bfd, 0);
        if (vmap == NULL)
        {
            /* Make sure to close exec_bfd, or else "run" might try to use
               it.  */
            exec_close ();
            error (_("\"%s\": can't find the file sections: %s"),
                   scratch_pathname, bfd_errmsg (bfd_get_error ()));
        }
#endif /* DEPRECATED_IBM6000_TARGET */

        if (build_section_table (exec_bfd, &sections, &sections_end))
        {
            /* Make sure to close exec_bfd, or else "run" might try to use
               it.  */
            exec_close ();
            error (_("\"%s\": can't find the file sections: %s"),
                   scratch_pathname, bfd_errmsg (bfd_get_error ()));
        }

        exec_bfd_mtime = bfd_get_mtime (exec_bfd);

        validate_files ();

        set_gdbarch_from_file (exec_bfd);

        /* Add the executable's sections to the current address spaces'
        list of sections.  This possibly pushes the exec_ops
         target.  */
        add_target_sections (&exec_bfd, sections, sections_end);
        xfree (sections);

        /* Tell display code (if any) about the changed file name.  */
        if (deprecated_exec_file_display_hook)
            (*deprecated_exec_file_display_hook) (filename);

        do_cleanups (cleanups);
    }
    bfd_cache_close_all ();
    observer_notify_executable_changed ();
}
Ejemplo n.º 14
0
Archivo: main.c Proyecto: aosm/gdb
static int
captured_main (void *data)
{
  /* If you add initializations here, you also need to add then to the
     proc do_steps_and_nexts in selftest.exp.  */
  struct captured_main_args *context = data;
  int argc = context->argc;
  char **argv = context->argv;
  int count;
  static int quiet = 0;
  static int batch = 0;
  static int set_args = 0;

  /* Pointers to various arguments from command line.  */
  char *symarg = NULL;
  char *execarg = NULL;
  char *corearg = NULL;
  char *cdarg = NULL;
  char *ttyarg = NULL;
  /* APPLE LOCAL: Set the osabi via option.  */
  char *osabiarg = NULL;  


  /* These are static so that we can take their address in an initializer.  */
  static int print_help;
  static int print_version;

  /* Pointers to all arguments of --command option.  */
  char **cmdarg;
  /* Allocated size of cmdarg.  */
  int cmdsize;
  /* Number of elements of cmdarg used.  */
  int ncmd;

  /* Indices of all arguments of --directory option.  */
  char **dirarg;
  /* Allocated size.  */
  int dirsize;
  /* Number of elements used.  */
  int ndir;

  /* APPLE LOCAL globalbuf */
  struct stat homebuf, cwdbuf, globalbuf;
  char *homedir;
  /* APPLE LOCAL attach -waitfor */
  char *attach_waitfor = NULL;
  /* APPLE LOCAL: set the architecture.  */
  char *initial_arch = NULL;

  int i;

  long time_at_startup = get_run_time ();

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
  setlocale (LC_CTYPE, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  /* APPLE LOCAL memory */
#ifdef USE_MMALLOC
  init_mmalloc_default_pool ((PTR) NULL);
#endif
 
  /* This needs to happen before the first use of malloc.  */
  init_malloc (NULL);

#ifdef HAVE_SBRK
  lim_at_start = (char *) sbrk (0);
#endif

#if defined (ALIGN_STACK_ON_STARTUP)
  i = (int) &count & 0x3;
  if (i != 0)
    alloca (4 - i);
#endif

  cmdsize = 1;
  cmdarg = (char **) xmalloc (cmdsize * sizeof (*cmdarg));
  ncmd = 0;
  dirsize = 1;
  dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
  ndir = 0;

  quit_flag = 0;
  line = (char *) xmalloc (linesize);
  line[0] = '\0';		/* Terminate saved (now empty) cmd line */
  instream = stdin;

  getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
  current_directory = gdb_dirbuf;

  /* APPLE LOCAL gdb_null */
  gdb_null = ui_file_new ();
  gdb_stdout = stdio_fileopen (stdout);
  gdb_stderr = stdio_fileopen (stderr);
  gdb_stdlog = gdb_stderr;	/* for moment */
  gdb_stdtarg = gdb_stderr;	/* for moment */
  gdb_stdin = stdio_fileopen (stdin);
  gdb_stdtargerr = gdb_stderr;	/* for moment */
  gdb_stdtargin = gdb_stdin;	/* for moment */

  /* APPLE LOCAL: set our main thread's name */
#ifdef HAVE_PTHREAD_SETNAME_NP
  pthread_setname_np ("gdb main thread");
#endif

  /* Set the sysroot path.  */
#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
  gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
  if (gdb_sysroot)
    {
      struct stat s;
      int res = 0;

      if (stat (gdb_sysroot, &s) == 0)
	if (S_ISDIR (s.st_mode))
	  res = 1;

      if (res == 0)
	{
	  xfree (gdb_sysroot);
	  gdb_sysroot = TARGET_SYSTEM_ROOT;
	}
    }
  else
    gdb_sysroot = TARGET_SYSTEM_ROOT;
#else
#if defined (TARGET_SYSTEM_ROOT)
  gdb_sysroot = TARGET_SYSTEM_ROOT;
#else
  gdb_sysroot = "";
#endif
#endif

  /* There will always be an interpreter.  Either the one passed into
     this captured main, or one specified by the user at start up, or
     the console.  Initialize the interpreter to the one requested by 
     the application.  */
  interpreter_p = xstrdup (context->interpreter_p);

  /* Parse arguments and options.  */
  {
    int c;
    /* When var field is 0, use flag field to record the equivalent
       short option (or arbitrary numbers starting at 10 for those
       with no equivalent).  */
    enum {
      OPT_SE = 10,
      OPT_CD,
      OPT_ANNOTATE,
      OPT_STATISTICS,
      OPT_TUI,
      OPT_NOWINDOWS,
      OPT_WINDOWS,
      OPT_WAITFOR,  /* APPLE LOCAL */
      OPT_ARCH,     /* APPLE LOCAL */
      OPT_OSABI	    /* APPLE LOCAL */
    };
    static struct option long_options[] =
    {
#if defined(TUI)
      {"tui", no_argument, 0, OPT_TUI},
#endif
      {"xdb", no_argument, &xdb_commands, 1},
      {"dbx", no_argument, &dbx_commands, 1},
      {"readnow", no_argument, &readnow_symbol_files, 1},
      {"r", no_argument, &readnow_symbol_files, 1},
      {"quiet", no_argument, &quiet, 1},
      {"q", no_argument, &quiet, 1},
      {"silent", no_argument, &quiet, 1},
      {"nx", no_argument, &inhibit_gdbinit, 1},
      {"n", no_argument, &inhibit_gdbinit, 1},
      {"batch", no_argument, &batch, 1},
      {"epoch", no_argument, &epoch_interface, 1},

    /* This is a synonym for "--annotate=1".  --annotate is now preferred,
       but keep this here for a long time because people will be running
       emacses which use --fullname.  */
      {"fullname", no_argument, 0, 'f'},
      {"f", no_argument, 0, 'f'},

      {"annotate", required_argument, 0, OPT_ANNOTATE},
      {"help", no_argument, &print_help, 1},
      {"se", required_argument, 0, OPT_SE},
      {"symbols", required_argument, 0, 's'},
      {"s", required_argument, 0, 's'},
      {"exec", required_argument, 0, 'e'},
      {"e", required_argument, 0, 'e'},
      {"core", required_argument, 0, 'c'},
      {"c", required_argument, 0, 'c'},
      {"pid", required_argument, 0, 'p'},
      {"p", required_argument, 0, 'p'},
      {"command", required_argument, 0, 'x'},
      {"version", no_argument, &print_version, 1},
      {"x", required_argument, 0, 'x'},
#ifdef GDBTK
      {"tclcommand", required_argument, 0, 'z'},
      {"enable-external-editor", no_argument, 0, 'y'},
      {"editor-command", required_argument, 0, 'w'},
#endif
      {"ui", required_argument, 0, 'i'},
      {"interpreter", required_argument, 0, 'i'},
      {"i", required_argument, 0, 'i'},
      {"directory", required_argument, 0, 'd'},
      {"d", required_argument, 0, 'd'},
      {"cd", required_argument, 0, OPT_CD},
      {"tty", required_argument, 0, 't'},
      {"baud", required_argument, 0, 'b'},
      {"b", required_argument, 0, 'b'},
      {"nw", no_argument, NULL, OPT_NOWINDOWS},
      {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
      {"w", no_argument, NULL, OPT_WINDOWS},
      {"windows", no_argument, NULL, OPT_WINDOWS},
      {"statistics", no_argument, 0, OPT_STATISTICS},
      {"write", no_argument, &write_files, 1},
      {"args", no_argument, &set_args, 1},
/* APPLE LOCAL: */
      {"waitfor", required_argument, 0, OPT_WAITFOR},
/* APPLE LOCAL: */
      {"arch", required_argument, 0, OPT_ARCH},
/* APPLE LOCAL: */
      {"osabi", required_argument, 0, OPT_OSABI},
      {"l", required_argument, 0, 'l'},
      {0, no_argument, 0, 0}
    };

    while (1)
      {
	int option_index;

	c = getopt_long_only (argc, argv, "",
			      long_options, &option_index);
	if (c == EOF || set_args)
	  break;

	/* Long option that takes an argument.  */
	if (c == 0 && long_options[option_index].flag == 0)
	  c = long_options[option_index].val;

	switch (c)
	  {
	  case 0:
	    /* Long option that just sets a flag.  */
	    break;
	  case OPT_SE:
	    symarg = optarg;
	    execarg = optarg;
	    break;
	  case OPT_CD:
	    cdarg = optarg;
	    break;
	  case OPT_ANNOTATE:
	    /* FIXME: what if the syntax is wrong (e.g. not digits)?  */
	    annotation_level = atoi (optarg);
	    break;
	  case OPT_STATISTICS:
	    /* Enable the display of both time and space usage.  */
	    display_time = 1;
	    display_space = 1;
	    break;
	  case OPT_TUI:
	    /* --tui is equivalent to -i=tui.  */
	    xfree (interpreter_p);
	    interpreter_p = xstrdup ("tui");
	    break;
	  case OPT_WINDOWS:
	    /* FIXME: cagney/2003-03-01: Not sure if this option is
               actually useful, and if it is, what it should do.  */
	    use_windows = 1;
	    break;
	  case OPT_NOWINDOWS:
	    /* -nw is equivalent to -i=console.  */
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (INTERP_CONSOLE);
	    use_windows = 0;
	    break;
	  /* APPLE LOCAL: */
	  case OPT_WAITFOR:
	    attach_waitfor = (char *) xmalloc (12 + strlen (optarg));
	    sprintf (attach_waitfor, "-waitfor \"%s\"", optarg);
	    break;
	  /* APPLE LOCAL: */
	  case OPT_ARCH:
	    initial_arch = xstrdup (optarg);
	    break;
	  /* APPLE LOCAL: Set the osabi via option. This option was 
	     added along with a modification to the gdb driver shell script
	     for armv6. Binaries with the "arm" architecture (ARM v4T)
	     and "armv6" (ARM v6) can be inter mixed on armv6 capaable 
	     targets since all instructions in the ARM v4T instruction set
	     are present in the ARM v6 instruction set. The same gdb
	     executable is used for both, and the osabi set/show variable
	     controls which gets used for cross targets. We need to set this
	     variable prior to loading any executables so that the correct
	     slice of a fat file can be selected. Now gdb can be launched
	     with the "armv6" arch along with an executable and the correct
	     slice will be selected:
	     gdb -arch armv6 <file>  */
	  case OPT_OSABI:
	    osabiarg = optarg;
	    break;
	  /* APPLE LOCAL END */
	  case 'f':
	    annotation_level = 1;
/* We have probably been invoked from emacs.  Disable window interface.  */
	    use_windows = 0;
	    break;
	  case 's':
	    symarg = optarg;
	    break;
	  case 'e':
	    execarg = optarg;
	    break;
	  case 'c':
	    corearg = optarg;
	    break;
	  case 'p':
	    /* "corearg" is shared by "--core" and "--pid" */
	    corearg = optarg;
	    break;
	  case 'x':
	    cmdarg[ncmd++] = optarg;
	    if (ncmd >= cmdsize)
	      {
		cmdsize *= 2;
		cmdarg = (char **) xrealloc ((char *) cmdarg,
					     cmdsize * sizeof (*cmdarg));
	      }
	    break;
#ifdef GDBTK
	  case 'z':
	    {
extern int gdbtk_test (char *);
	      if (!gdbtk_test (optarg))
		{
		  fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""),
				      argv[0], optarg);
		  exit (1);
		}
	      break;
	    }
	  case 'y':
	    /* Backwards compatibility only.  */
	    break;
	  case 'w':
	    {
	      external_editor_command = xstrdup (optarg);
	      break;
	    }
#endif /* GDBTK */
	  case 'i':
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (optarg);
	    break;
	  case 'd':
	    dirarg[ndir++] = optarg;
	    if (ndir >= dirsize)
	      {
		dirsize *= 2;
		dirarg = (char **) xrealloc ((char *) dirarg,
					     dirsize * sizeof (*dirarg));
	      }
	    break;
	  case 't':
	    ttyarg = optarg;
	    break;
	  case 'q':
	    quiet = 1;
	    break;
	  case 'b':
	    {
	      int i;
	      char *p;

	      i = strtol (optarg, &p, 0);
	      if (i == 0 && p == optarg)

		/* Don't use *_filtered or warning() (which relies on
		   current_target) until after initialize_all_files(). */

		fprintf_unfiltered
		  (gdb_stderr,
		   _("warning: could not set baud rate to `%s'.\n"), optarg);
	      else
		baud_rate = i;
	    }
            break;
	  case 'l':
	    {
	      int i;
	      char *p;

	      i = strtol (optarg, &p, 0);
	      if (i == 0 && p == optarg)

		/* Don't use *_filtered or warning() (which relies on
		   current_target) until after initialize_all_files(). */

		fprintf_unfiltered
		  (gdb_stderr,
		 _("warning: could not set timeout limit to `%s'.\n"), optarg);
	      else
		remote_timeout = i;
	    }
	    break;

	  case '?':
	    fprintf_unfiltered (gdb_stderr,
			_("Use `%s --help' for a complete list of options.\n"),
				argv[0]);
	    exit (1);
	  }
      }

    /* If --help or --version, disable window interface.  */
    if (print_help || print_version)
      {
	use_windows = 0;
      }

    if (set_args)
      {
	/* The remaining options are the command-line options for the
	   inferior.  The first one is the sym/exec file, and the rest
	   are arguments.  */
	if (optind >= argc)
	  {
	    fprintf_unfiltered (gdb_stderr,
				_("%s: `--args' specified but no program specified\n"),
				argv[0]);
	    exit (1);
	  }
	symarg = argv[optind];
	execarg = argv[optind];
	++optind;
	set_inferior_args_vector (argc - optind, &argv[optind]);
      }
    else
      {
	/* OK, that's all the options.  The other arguments are filenames.  */
	count = 0;
	for (; optind < argc; optind++)
	  switch (++count)
	    {
	    case 1:
	      symarg = argv[optind];
	      execarg = argv[optind];
	      break;
	    case 2:
	      /* The documentation says this can be a "ProcID" as well. 
	         We will try it as both a corefile and a pid.  */
	      corearg = argv[optind];
	      break;
	    case 3:
	      fprintf_unfiltered (gdb_stderr,
				  _("Excess command line arguments ignored. (%s%s)\n"),
				  argv[optind], (optind == argc - 1) ? "" : " ...");
	      break;
	    }
      }
    if (batch)
      quiet = 1;
  }

  /* Initialize all files.  Give the interpreter a chance to take
     control of the console via the deprecated_init_ui_hook ().  */
  gdb_init (argv[0]);

  /* Do these (and anything which might call wrap_here or *_filtered)
     after initialize_all_files() but before the interpreter has been
     installed.  Otherwize the help/version messages will be eaten by
     the interpreter's output handler.  */

  if (print_version)
    {
      print_gdb_version (gdb_stdout);
      wrap_here ("");
      printf_filtered ("\n");
      exit (0);
    }

  if (print_help)
    {
      print_gdb_help (gdb_stdout);
      fputs_unfiltered ("\n", gdb_stdout);
      exit (0);
    }

  /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
     GDB retain the old MI1 interpreter startup behavior.  Output the
     copyright message before the interpreter is installed.  That way
     it isn't encapsulated in MI output.  */
  if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
    {
      /* APPLE LOCAL begin don't print dots */
      /* Print all the junk at the top. */
      print_gdb_version (gdb_stdout);
      printf_filtered ("\n");
      /* APPLE LOCAL end don't print dots */
      wrap_here ("");
      gdb_flush (gdb_stdout);	/* Force to screen during slow operations */
    }


  /* APPLE LOCAL begin */
  if (state_change_hook)
    {
      state_change_hook (STATE_ACTIVE);
    }
  /* APPLE LOCAL end */
  
  /* Install the default UI.  All the interpreters should have had a
     look at things by now.  Initialize the default interpreter. */

  {
    /* Find it.  */
    struct interp *interp = interp_lookup (interpreter_p);
    if (interp == NULL)
      error (_("Interpreter `%s' unrecognized"), interpreter_p);
    /* Install it.  */
    /* APPLE LOCAL clarity */
    if (interp_set (interp) == NULL)
      {
        fprintf_unfiltered (gdb_stderr,
			    "Interpreter `%s' failed to initialize.\n",
                            interpreter_p);
        exit (1);
      }
  }

  /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
     GDB retain the old MI1 interpreter startup behavior.  Output the
     copyright message after the interpreter is installed when it is
     any sane interpreter.  */
  if (!quiet && !current_interp_named_p (INTERP_MI1))
    {
      /* Print all the junk at the top, with trailing "..." if we are about
         to read a symbol file (possibly slowly).  */
      print_gdb_version (gdb_stdout);
      if (symarg)
	printf_filtered ("..");
      wrap_here ("");
      gdb_flush (gdb_stdout);	/* Force to screen during slow operations */
    }

  error_pre_print = "\n\n";
  quit_pre_print = error_pre_print;

  /* We may get more than one warning, don't double space all of them... */
  warning_pre_print = _("\nwarning: ");

  /* APPLE LOCAL begin move inits up */
  /* Make sure that they are zero in case one of them fails (this
     guarantees that they won't match if either exists).  */
  
  memset (&homebuf, 0, sizeof (struct stat));
  memset (&cwdbuf, 0, sizeof (struct stat));
  /* APPLE LOCAL end move inits up */
  /* APPLE LOCAL begin global gdbinit */
  memset (&globalbuf, 0, sizeof (struct stat));
  stat (gdbinit_global, &globalbuf);
  if (!inhibit_gdbinit)
    {
      /* if (!SET_TOP_LEVEL ()) */
	 source_file (gdbinit_global, 0);
    }
  do_cleanups (ALL_CLEANUPS);
  /* APPLE LOCAL end global gdbinit */
 
  /* APPLE LOCAL: Set the $_Xcode convenience variable at '0' before sourcing
     any .gdbinit files.  Xcode will override this to 1 when it is launching
     gdb but we need to start with a value of 0 so .gdbinit files can use it 
     in conditional expressions.  */
  set_internalvar (lookup_internalvar ("_Xcode"),
                   value_from_longest (builtin_type_int, (LONGEST) 0));

  /* Read and execute $HOME/.gdbinit file, if it exists.  This is done
     *before* all the command line arguments are processed; it sets
     global parameters, which are independent of what file you are
     debugging or what directory you are in.  */
  homedir = getenv ("HOME");
  if (homedir)
    {
      char *homeinit = xstrprintf ("%s/%s", homedir, gdbinit);

      /* APPLE LOCAL move inits up */
      stat (homeinit, &homebuf);
      /* APPLE LOCAL gdbinit */
      if (!inhibit_gdbinit)
	if ((globalbuf.st_dev != homebuf.st_dev) || (globalbuf.st_ino != homebuf.st_ino))
	  {
	    catch_command_errors (source_file, homeinit, 0, RETURN_MASK_ALL);
	  }
    }

  /* Now perform all the actions indicated by the arguments.  */
  if (cdarg != NULL)
    {
      catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL);
    }

  for (i = 0; i < ndir; i++)
    catch_command_errors (directory_command, dirarg[i], 0, RETURN_MASK_ALL);
  xfree (dirarg);

  /* APPLE LOCAL: If an architecture has been supplied, process it. 
     FIXME: Note, this is a TOTAL hack.  There should be some gdbarch'y type
     function that processes these options.  The odd thing is that you would
     want the SAME function for all the gdbarch'es that are registered, so
     it actually lives a little above the gdbarch....  
     Not sure how to do that.  So instead, I just hack...  */
#if defined (USE_POSIX_SPAWN) || defined (USE_ARCH_FOR_EXEC)
  if (initial_arch != NULL)
    {
      char *arch_string = NULL;
      char *osabi_string;
#if defined (TARGET_POWERPC)
      if (strcmp (initial_arch, "ppc") == 0)
	{
	  arch_string = "powerpc:common";
	  osabi_string = "Darwin";
	}
      else if (strcmp (initial_arch, "ppc64") == 0)
	{
	  arch_string = "powerpc:common64";
	  osabi_string = "Darwin64";
	}
      else
	  warning ("invalid argument \"%s\" for \"--arch\", should be one of "
		 "\"ppc\" or \"ppc64\"\n", initial_arch);
#elif defined (TARGET_I386)
      if (strcmp (initial_arch, "i386") == 0)
	{
	  arch_string = "i386";
	  osabi_string = "Darwin";
	}
      else if (strcmp (initial_arch, "x86_64") == 0)
	{
	  arch_string = "i386:x86-64";
	  osabi_string = "Darwin64";
	}
      else
	warning ("invalid argument \"%s\" for \"--arch\", should be one of "
		 "\"i386\" or \"x86_64\"\n", initial_arch);
#elif defined (TARGET_ARM)
      if (strcmp (initial_arch, "arm") == 0)
	{
	  arch_string = "arm";
	  osabi_string = "Darwin";
	}
      else if (strcmp (initial_arch, "armv6") == 0)
	{
	  arch_string = "armv6";
	  osabi_string = "DarwinV6";
	}
      else
	warning ("invalid argument \"%s\" for \"--arch\", should be one of "
		 "\"armv\" or \"armv6\"\n", initial_arch);
#endif
      if (arch_string != NULL)
	{
	  set_architecture_from_string (arch_string);
	  set_osabi_from_string (osabi_string);
	}
    }
#else
  warning ("--arch option not supported in this gdb.");
#endif

  /* APPLE LOCAL BEGIN: Set the osabi via option.  */
  if (osabiarg != NULL)
    set_osabi_option (osabiarg);
  /* APPLE LOCAL END */

  if (execarg != NULL
      && symarg != NULL
      && strcmp (execarg, symarg) == 0)
    {
      /* The exec file and the symbol-file are the same.  If we can't
         open it, better only print one error message.
         catch_command_errors returns non-zero on success! */
      if (catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL))
	catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
    }
  else
    {
      if (execarg != NULL)
	catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL);
      if (symarg != NULL)
	catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
    }

  /* APPLE LOCAL begin */
  if (state_change_hook && symarg != NULL)
    {
      state_change_hook (STATE_INFERIOR_LOADED);
    }
  /* APPLE LOCAL end */
  
  /* APPLE LOCAL begin */
  if (attach_waitfor != NULL)
    {
      printf_filtered ("\n");
      catch_command_errors (attach_command, attach_waitfor, 0, RETURN_MASK_ALL);
    }
    
  /* After the symbol file has been read, print a newline to get us
     beyond the copyright line...  But errors should still set off
     the error message with a (single) blank line.  */
  if (!quiet)
    printf_filtered ("\n");
  error_pre_print = "\n";
  quit_pre_print = error_pre_print;
  warning_pre_print = _("\nwarning: ");

  if (corearg != NULL)
    {
      if (catch_command_errors (core_file_attach, corearg, !batch, RETURN_MASK_ALL) == 0)
	{
	  /* See if the core file is really a PID. */
	  /* Be careful, we have quoted the corearg above... */
	  if (corearg[0] == '"')
	    {
	      int len = strlen (corearg);
	      if (corearg[len - 1] == '"')
		{
		  corearg[len - 1] = '\0';
		  corearg += 1;
		}
	    }

	  if (isdigit (corearg[0]))
	    catch_command_errors (attach_command, corearg, !batch, RETURN_MASK_ALL);
	}
    }

  if (ttyarg != NULL)
    catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);

  /* Error messages should no longer be distinguished with extra output. */
  error_pre_print = NULL;
  quit_pre_print = NULL;
  warning_pre_print = _("warning: ");

  /* Read the .gdbinit file in the current directory, *if* it isn't
     the same as the $HOME/.gdbinit file (it should exist, also).  */

  stat (gdbinit, &cwdbuf);
  if (!inhibit_gdbinit)
    if (((globalbuf.st_dev != cwdbuf.st_dev) || (globalbuf.st_ino != cwdbuf.st_ino))
	&& ((homebuf.st_dev != cwdbuf.st_dev) || (homebuf.st_ino != cwdbuf.st_ino)))
      {
        /* APPLE LOCAL: fix for CVE-2005-1705 */
        if (cwdbuf.st_uid == getuid ())
	  catch_command_errors (source_file, gdbinit, 0, RETURN_MASK_ALL);
      }
  
  /* These need to be set this late in the initialization to ensure that
     they are defined for the current environment.  They define the
     radix variables needed by a save-breakpoints file to preserve the
     radix across the breakpoints restoration assuming they are restored
     using the -x (-command) command line options.  */
     
  set_internalvar (lookup_internalvar ("input_radix"),
		   value_from_longest (builtin_type_int, (LONGEST) input_radix));
  set_internalvar (lookup_internalvar ("output_radix"),
		   value_from_longest (builtin_type_int, (LONGEST) output_radix));

  for (i = 0; i < ncmd; i++)
    {
#if 0
      /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that
         expanded into a call to setjmp().  */
      if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */
	{
	  /* NOTE: I am commenting this out, because it is not clear
	     where this feature is used. It is very old and
	     undocumented. ezannoni: 1999-05-04 */
#if 0
	  if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
	    read_command_file (stdin);
	  else
#endif
	    source_file (cmdarg[i], !batch);
	  do_cleanups (ALL_CLEANUPS);
	}
#endif
      catch_command_errors (source_file, cmdarg[i], !batch, RETURN_MASK_ALL);
    }
  xfree (cmdarg);

  /* Read in the old history after all the command files have been read. */
  init_history ();

  if (batch)
    {
      if (attach_flag)
	/* Either there was a problem executing the command in the
	   batch file aborted early, or the batch file forgot to do an
	   explicit detach.  Explicitly detach the inferior ensuring
	   that there are no zombies.  */
	target_detach (NULL, 0);
      
      /* We have hit the end of the batch file.  */
      exit (0);
    }

  /* Do any host- or target-specific hacks.  This is used for i960 targets
     to force the user to set a nindy target and spec its parameters.  */

#ifdef BEFORE_MAIN_LOOP_HOOK
  BEFORE_MAIN_LOOP_HOOK;
#endif

  /* Show time and/or space usage.  */

  if (display_time)
    {
      long init_time = get_run_time () - time_at_startup;

      printf_unfiltered (_("Startup time: %ld.%06ld\n"),
			 init_time / 1000000, init_time % 1000000);
    }

  if (display_space)
    {
#ifdef HAVE_SBRK
      extern char **environ;
      char *lim = (char *) sbrk (0);

      printf_unfiltered (_("Startup size: data size %ld\n"),
			 (long) (lim - (char *) &environ));
#endif
    }

#if 0
  /* FIXME: cagney/1999-11-06: The original main loop was like: */
  while (1)
    {
      if (!SET_TOP_LEVEL ())
	{
	  do_cleanups (ALL_CLEANUPS);	/* Do complete cleanup */
	  /* GUIs generally have their own command loop, mainloop, or
	     whatever.  This is a good place to gain control because
	     many error conditions will end up here via longjmp().  */
	  if (deprecated_command_loop_hook)
	    deprecated_command_loop_hook ();
	  else
	    deprecated_command_loop ();
	  quit_command ((char *) 0, instream == stdin);
	}
    }
  /* NOTE: If the command_loop() returned normally, the loop would
     attempt to exit by calling the function quit_command().  That
     function would either call exit() or throw an error returning
     control to SET_TOP_LEVEL. */
  /* NOTE: The function do_cleanups() was called once each time round
     the loop.  The usefulness of the call isn't clear.  If an error
     was thrown, everything would have already been cleaned up.  If
     command_loop() returned normally and quit_command() was called,
     either exit() or error() (again cleaning up) would be called. */
#endif
  /* NOTE: cagney/1999-11-07: There is probably no reason for not
     moving this loop and the code found in captured_command_loop()
     into the command_loop() proper.  The main thing holding back that
     change - SET_TOP_LEVEL() - has been eliminated. */
  while (1)
    {
      catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
    }
  /* No exit -- exit is through quit_command.  */
}
Ejemplo n.º 15
0
static void
info_command (char *arg, int from_tty)
{
  printf_unfiltered (_("\"info\" must be followed by the name of an info command.\n"));
  help_list (infolist, "info ", -1, gdb_stdout);
}
Ejemplo n.º 16
0
static void
info_mach_ports_command (char *args, int from_tty)
{
  port_name_array_t names;
  port_type_array_t types;
  unsigned int name_count, type_count;
  kern_return_t result;
  int index;
  task_t task;

  task = get_task_from_args (args);
  if (task == TASK_NULL)
    return;

  result = mach_port_names (task, &names, &name_count, &types, &type_count);
  MACH_CHECK_ERROR (result);

  gdb_assert (name_count == type_count);

  printf_unfiltered (_("Ports for task 0x%x:\n"), task);
  printf_unfiltered (_("port   type\n"));
  for (index = 0; index < name_count; ++index)
    {
      mach_port_t port = names[index];
      unsigned int j;
      struct type_descr
      {
	mach_port_type_t type;
	const char *name;
	mach_port_right_t right;
      };
      static struct type_descr descrs[] =
	{
	  {MACH_PORT_TYPE_SEND, "send", MACH_PORT_RIGHT_SEND},
	  {MACH_PORT_TYPE_SEND_ONCE, "send-once", MACH_PORT_RIGHT_SEND_ONCE},
	  {MACH_PORT_TYPE_RECEIVE, "receive", MACH_PORT_RIGHT_RECEIVE},
	  {MACH_PORT_TYPE_PORT_SET, "port-set", MACH_PORT_RIGHT_PORT_SET},
	  {MACH_PORT_TYPE_DEAD_NAME, "dead", MACH_PORT_RIGHT_DEAD_NAME}
	};

      printf_unfiltered (_("%04x: %08x "), port, types[index]);
      for (j = 0; j < sizeof(descrs) / sizeof(*descrs); j++)
	if (types[index] & descrs[j].type)
	  {
	    mach_port_urefs_t ref;
	    kern_return_t ret;

	    printf_unfiltered (_(" %s("), descrs[j].name);
	    ret = mach_port_get_refs (task, port, descrs[j].right, &ref);
	    if (ret != KERN_SUCCESS)
	      printf_unfiltered (_("??"));
	    else
	      printf_unfiltered (_("%u"), ref);
	    printf_unfiltered (_(" refs)"));
	  }
      
      if (task == task_self ())
	{
	  if (port == task_self())
	    printf_unfiltered (_(" gdb-task"));
	  else if (port == darwin_host_self)
	    printf_unfiltered (_(" host-self"));
	  else if (port == darwin_ex_port)
	    printf_unfiltered (_(" gdb-exception"));
	  else if (port == darwin_port_set)
	    printf_unfiltered (_(" gdb-port_set"));
	  else if (!ptid_equal (inferior_ptid, null_ptid))
	    {
	      struct inferior *inf = current_inferior ();

	      if (port == inf->priv->task)
		printf_unfiltered (_(" inferior-task"));
	      else if (port == inf->priv->notify_port)
		printf_unfiltered (_(" inferior-notify"));
	      else
		{
		  int k;
		  darwin_thread_t *t;

		  for (k = 0; k < inf->priv->exception_info.count; k++)
		    if (port == inf->priv->exception_info.ports[k])
		      {
			printf_unfiltered (_(" inferior-excp-port"));
			break;
		      }

		  if (inf->priv->threads)
		    {
		      for (k = 0;
			   VEC_iterate(darwin_thread_t,
				       inf->priv->threads, k, t);
			   k++)
			if (port == t->gdb_port)
			  {
			    printf_unfiltered (_(" inferior-thread for 0x%x"),
					       inf->priv->task);
			    break;
			  }
		    }
		}
	    }
	}
      printf_unfiltered (_("\n"));
    }

  vm_deallocate (task_self (), (vm_address_t) names,
                 (name_count * sizeof (mach_port_t)));
  vm_deallocate (task_self (), (vm_address_t) types,
                 (type_count * sizeof (mach_port_type_t)));
}
Ejemplo n.º 17
0
static void
complete_command (char *arg, int from_tty)
{
  int argpoint;
  char **completions, *point, *arg_prefix;

  dont_repeat ();

  if (arg == NULL)
    arg = "";
  argpoint = strlen (arg);

  /* complete_line assumes that its first argument is somewhere within,
     and except for filenames at the beginning of, the word to be completed.
     The following crude imitation of readline's word-breaking tries to
     accomodate this.  */
  point = arg + argpoint;
  while (point > arg)
    {
      if (strchr (rl_completer_word_break_characters, point[-1]) != 0)
        break;
      point--;
    }

  arg_prefix = alloca (point - arg + 1);
  memcpy (arg_prefix, arg, point - arg);
  arg_prefix[point - arg] = 0;

  completions = complete_line (point, arg, argpoint);

  if (completions)
    {
      int item, size;

      for (size = 0; completions[size]; ++size)
	;
      qsort (completions, size, sizeof (char *), compare_strings);

      /* We do extra processing here since we only want to print each
	 unique item once.  */
      item = 0;
      while (item < size)
	{
	  int next_item;

	  printf_unfiltered ("%s%s\n", arg_prefix, completions[item]);
	  next_item = item + 1;
	  while (next_item < size
		 && ! strcmp (completions[item], completions[next_item]))
	    {
	      xfree (completions[next_item]);
	      ++next_item;
	    }

	  xfree (completions[item]);
	  item = next_item;
	}

      xfree (completions);
    }
}
Ejemplo n.º 18
0
static void
darwin_debug_port_info (task_t task, mach_port_t port)
{
  kern_return_t kret;
  mach_port_status_t status;
  mach_msg_type_number_t len = sizeof (status);

  kret = mach_port_get_attributes
    (task, port, MACH_PORT_RECEIVE_STATUS, (mach_port_info_t)&status, &len);
  MACH_CHECK_ERROR (kret);

  printf_unfiltered (_("Port 0x%lx in task 0x%lx:\n"), (unsigned long) port,
                     (unsigned long) task);
  printf_unfiltered (_("  port set: 0x%x\n"), status.mps_pset);
  printf_unfiltered (_("     seqno: 0x%x\n"), status.mps_seqno);
  printf_unfiltered (_("   mscount: 0x%x\n"), status.mps_mscount);
  printf_unfiltered (_("    qlimit: 0x%x\n"), status.mps_qlimit);
  printf_unfiltered (_("  msgcount: 0x%x\n"), status.mps_msgcount);
  printf_unfiltered (_("  sorights: 0x%x\n"), status.mps_sorights);
  printf_unfiltered (_("   srights: 0x%x\n"), status.mps_srights);
  printf_unfiltered (_(" pdrequest: 0x%x\n"), status.mps_pdrequest);
  printf_unfiltered (_(" nsrequest: 0x%x\n"), status.mps_nsrequest);
  printf_unfiltered (_("     flags: 0x%x\n"), status.mps_flags);
}
Ejemplo n.º 19
0
/* Read register values from the inferior process.
   If REGNO is -1, do this for all registers.
   Otherwise, REGNO specifies which register (so we can save time).  */
static void
i386_darwin_fetch_inferior_registers (struct target_ops *ops,
				      struct regcache *regcache, int regno)
{
  thread_t current_thread = ptid_get_tid (inferior_ptid);
  int fetched = 0;
  struct gdbarch *gdbarch = get_regcache_arch (regcache);

#ifdef BFD64
  if (gdbarch_ptr_bit (gdbarch) == 64)
    {
      if (regno == -1 || amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_thread_state_t gp_regs;
          unsigned int gp_count = x86_THREAD_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, x86_THREAD_STATE, (thread_state_t) & gp_regs,
             &gp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "GP registers for thread 0x%lx\n"),
				 (unsigned long) current_thread);
	      MACH_CHECK_ERROR (ret);
	    }

	  /* Some kernels don't sanitize the values.  */
	  gp_regs.uts.ts64.__fs &= 0xffff;
	  gp_regs.uts.ts64.__gs &= 0xffff;

	  amd64_supply_native_gregset (regcache, &gp_regs.uts, -1);
          fetched++;
        }

      if (regno == -1 || !amd64_native_gregset_supplies_p (gdbarch, regno))
        {
          x86_float_state_t fp_regs;
          unsigned int fp_count = x86_FLOAT_STATE_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, x86_FLOAT_STATE, (thread_state_t) & fp_regs,
             &fp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "float registers for thread 0x%lx\n"),
				 (unsigned long) current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
          amd64_supply_fxsave (regcache, -1, &fp_regs.ufs.fs64.__fpu_fcw);
          fetched++;
        }
    }
  else
#endif
    {
      if (regno == -1 || regno < I386_NUM_GREGS)
        {
          x86_thread_state32_t gp_regs;
          unsigned int gp_count = x86_THREAD_STATE32_COUNT;
          kern_return_t ret;
	  int i;

	  ret = thread_get_state
            (current_thread, x86_THREAD_STATE32, (thread_state_t) &gp_regs,
             &gp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "GP registers for thread 0x%lx\n"),
				 (unsigned long) current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
	  for (i = 0; i < I386_NUM_GREGS; i++)
	    regcache_raw_supply
	      (regcache, i,
	       (char *)&gp_regs + i386_darwin_thread_state_reg_offset[i]);

          fetched++;
        }

      if (regno == -1
	  || (regno >= I386_ST0_REGNUM && regno < I386_SSE_NUM_REGS))
        {
          x86_float_state32_t fp_regs;
          unsigned int fp_count = x86_FLOAT_STATE32_COUNT;
          kern_return_t ret;

	  ret = thread_get_state
            (current_thread, x86_FLOAT_STATE32, (thread_state_t) &fp_regs,
             &fp_count);
	  if (ret != KERN_SUCCESS)
	    {
	      printf_unfiltered (_("Error calling thread_get_state for "
				   "float registers for thread 0x%lx\n"),
				 (unsigned long) current_thread);
	      MACH_CHECK_ERROR (ret);
	    }
          i387_supply_fxsave (regcache, -1, &fp_regs.__fpu_fcw);
          fetched++;
        }
    }

  if (! fetched)
    {
      warning (_("unknown register %d"), regno);
      regcache_raw_supply (regcache, regno, NULL);
    }
}
Ejemplo n.º 20
0
static void
disp_exception (const darwin_exception_info *info)
{
  int i;

  printf_filtered (_("%d exceptions:\n"), info->count);
  for (i = 0; i < info->count; i++)
    {
      exception_mask_t mask = info->masks[i];

      printf_filtered (_("port 0x%04x, behavior: "), info->ports[i]);
      switch (info->behaviors[i])
	{
	case EXCEPTION_DEFAULT:
	  printf_unfiltered (_("default"));
	  break;
	case EXCEPTION_STATE:
	  printf_unfiltered (_("state"));
	  break;
	case EXCEPTION_STATE_IDENTITY:
	  printf_unfiltered (_("state-identity"));
	  break;
	default:
	  printf_unfiltered (_("0x%x"), info->behaviors[i]);
	}
      printf_unfiltered (_(", masks:"));
      if (mask & EXC_MASK_BAD_ACCESS)
	printf_unfiltered (_(" BAD_ACCESS"));
      if (mask & EXC_MASK_BAD_INSTRUCTION)
	printf_unfiltered (_(" BAD_INSTRUCTION"));
      if (mask & EXC_MASK_ARITHMETIC)
	printf_unfiltered (_(" ARITHMETIC"));
      if (mask & EXC_MASK_EMULATION)
	printf_unfiltered (_(" EMULATION"));
      if (mask & EXC_MASK_SOFTWARE)
	printf_unfiltered (_(" SOFTWARE"));
      if (mask & EXC_MASK_BREAKPOINT)
	printf_unfiltered (_(" BREAKPOINT"));
      if (mask & EXC_MASK_SYSCALL)
	printf_unfiltered (_(" SYSCALL"));
      if (mask & EXC_MASK_MACH_SYSCALL)
	printf_unfiltered (_(" MACH_SYSCALL"));
      if (mask & EXC_MASK_RPC_ALERT)
	printf_unfiltered (_(" RPC_ALERT"));
      if (mask & EXC_MASK_CRASH)
	printf_unfiltered (_(" CRASH"));
      printf_unfiltered (_("\n"));
    }
}
Ejemplo n.º 21
0
static void
haiku_child_files_info (struct target_ops *ignore)
{
  printf_unfiltered ("\tUsing the running image of %s %s.\n",
      attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
}
Ejemplo n.º 22
0
/* Function to display source in the source window.  */
enum tui_status
tui_set_source_content (struct symtab *s, 
			int line_no,
			int noerror)
{
  enum tui_status ret = TUI_FAILURE;

  if (s != (struct symtab *) NULL && s->filename != (char *) NULL)
    {
      FILE *stream;
      int i, desc, c, line_width, nlines;
      char *src_line = 0;

      if ((ret = tui_alloc_source_buffer (TUI_SRC_WIN)) == TUI_SUCCESS)
	{
	  line_width = TUI_SRC_WIN->generic.width - 1;
	  /* Take hilite (window border) into account, when
	     calculating the number of lines.  */
	  nlines = (line_no + (TUI_SRC_WIN->generic.height - 2)) - line_no;
	  desc = open_source_file (s);
	  if (desc < 0)
	    {
	      if (!noerror)
		{
		  char *name = alloca (strlen (s->filename) + 100);
		  sprintf (name, "%s:%d", s->filename, line_no);
		  print_sys_errmsg (name, errno);
		}
	      ret = TUI_FAILURE;
	    }
	  else
	    {
	      if (s->line_charpos == 0)
		find_source_lines (s, desc);

	      if (line_no < 1 || line_no > s->nlines)
		{
		  close (desc);
		  printf_unfiltered (
			  "Line number %d out of range; %s has %d lines.\n",
				      line_no, s->filename, s->nlines);
		}
	      else if (lseek (desc, s->line_charpos[line_no - 1], 0) < 0)
		{
		  close (desc);
		  perror_with_name (s->filename);
		}
	      else
		{
		  int offset, cur_line_no, cur_line, cur_len, threshold;
		  struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
                  struct tui_source_info *src = &TUI_SRC_WIN->detail.source_info;

                  if (TUI_SRC_WIN->generic.title)
                    xfree (TUI_SRC_WIN->generic.title);
                  TUI_SRC_WIN->generic.title = xstrdup (s->filename);

                  if (src->filename)
                    xfree (src->filename);
                  src->filename = xstrdup (s->filename);

		  /* Determine the threshold for the length of the
                     line and the offset to start the display.  */
		  offset = src->horizontal_offset;
		  threshold = (line_width - 1) + offset;
		  stream = fdopen (desc, FOPEN_RT);
		  clearerr (stream);
		  cur_line = 0;
		  src->start_line_or_addr.loa = LOA_LINE;
		  cur_line_no = src->start_line_or_addr.u.line_no = line_no;
		  if (offset > 0)
		    src_line = (char *) xmalloc (
					   (threshold + 1) * sizeof (char));
		  while (cur_line < nlines)
		    {
		      struct tui_win_element *element = (struct tui_win_element *)
		      TUI_SRC_WIN->generic.content[cur_line];

		      /* Get the first character in the line.  */
		      c = fgetc (stream);

		      if (offset == 0)
			src_line = ((struct tui_win_element *)
				   TUI_SRC_WIN->generic.content[
					cur_line])->which_element.source.line;
		      /* Init the line with the line number.  */
		      sprintf (src_line, "%-6d", cur_line_no);
		      cur_len = strlen (src_line);
		      i = cur_len -
			((cur_len / tui_default_tab_len ()) * tui_default_tab_len ());
		      while (i < tui_default_tab_len ())
			{
			  src_line[cur_len] = ' ';
			  i++;
			  cur_len++;
			}
		      src_line[cur_len] = (char) 0;

		      /* Set whether element is the execution point
		         and whether there is a break point on it.  */
		      element->which_element.source.line_or_addr.loa =
			LOA_LINE;
		      element->which_element.source.line_or_addr.u.line_no =
			cur_line_no;
		      element->which_element.source.is_exec_point =
			(strcmp (((struct tui_win_element *)
				  locator->content[0])->which_element.locator.file_name,
				 s->filename) == 0
			 && cur_line_no == ((struct tui_win_element *)
					    locator->content[0])->which_element.locator.line_no);
		      if (c != EOF)
			{
			  i = strlen (src_line) - 1;
			  do
			    {
			      if ((c != '\n') && (c != '\r') 
				  && (++i < threshold))
				{
				  if (c < 040 && c != '\t')
				    {
				      src_line[i++] = '^';
				      src_line[i] = c + 0100;
				    }
				  else if (c == 0177)
				    {
				      src_line[i++] = '^';
				      src_line[i] = '?';
				    }
				  else
				    { /* Store the charcter in the
					 line buffer.  If it is a tab,
					 then translate to the correct
					 number of chars so we don't
					 overwrite our buffer.  */
				      if (c == '\t')
					{
					  int j, max_tab_len = tui_default_tab_len ();

					  for (j = i - ((i / max_tab_len) * max_tab_len);
					       j < max_tab_len
						 && i < threshold;
					       i++, j++)
					    src_line[i] = ' ';
					  i--;
					}
				      else
					src_line[i] = c;
				    }
				  src_line[i + 1] = 0;
				}
			      else
				{ /* If we have not reached EOL, then
				     eat chars until we do.  */
				  while (c != EOF && c != '\n' && c != '\r')
				    c = fgetc (stream);
				  /* Handle non-'\n' end-of-line.  */
				  if (c == '\r' 
				      && (c = fgetc (stream)) != '\n' 
				      && c != EOF)
				    {
				       ungetc (c, stream);
				       c = '\r';
				    }
				  
				}
			    }
			  while (c != EOF && c != '\n' && c != '\r' 
				 && i < threshold 
				 && (c = fgetc (stream)));
			}
		      /* Now copy the line taking the offset into
			 account.  */
		      if (strlen (src_line) > offset)
			strcpy (((struct tui_win_element *) TUI_SRC_WIN->generic.content[
					cur_line])->which_element.source.line,
				&src_line[offset]);
		      else
			((struct tui_win_element *)
			 TUI_SRC_WIN->generic.content[
			  cur_line])->which_element.source.line[0] = (char) 0;
		      cur_line++;
		      cur_line_no++;
		    }
		  if (offset > 0)
		    xfree (src_line);
		  fclose (stream);
		  TUI_SRC_WIN->generic.content_size = nlines;
		  ret = TUI_SUCCESS;
		}
	    }
	}
    }
  return ret;
}
Ejemplo n.º 23
0
static void
haiku_resume_thread(team_debug_info *teamDebugInfo, thread_debug_info *thread,
	int step, enum target_signal sig)
{
	thread_id threadID = (thread ? thread->thread : -1);
	int pendingSignal = -1;
	int signalToSend = target_to_haiku_signal(sig);
	uint32 handleEvent = B_THREAD_DEBUG_HANDLE_EVENT;

	if (!thread || !thread->stopped) {
		TRACE(("haiku_resume_thread(): thread %ld not stopped\n",
			threadID));
		return;
	}

	if (thread->reprocess_event > 0) {
		TRACE(("haiku_resume_thread(): thread %ld is expected to "
			"reprocess its current event\n", threadID));
		return;
	}

	// get the pending signal
	if (thread->last_event)
		pendingSignal = thread->signal;

	// Decide what to do with the event and the pending and passed signal.
	// We simply adjust signalToSend, pendingSignal and handleEvent.
	// If signalToSend is set afterwards, we need to send it. pendingSignal we
	// need to ignore. handleEvent specifies whether to handle/ignore the event.
	if (signalToSend > 0) {
		if (pendingSignal > 0) {
			if (signalToSend == pendingSignal) {
				// signal to send is the pending signal
				// we don't need to send it
				signalToSend = -1;
				if (thread->signal_status != SIGNAL_WILL_ARRIVE) {
					// the signal has not yet been sent, so we need to ignore
					// it only in this case, but not in the other ones
					pendingSignal = -1;
				}
			} else {
				// signal to send is not the pending signal
				// If the signal has been sent or will be sent, we need to
				// ignore the event.
				if (thread->signal_status != SIGNAL_FAKED)
					handleEvent = B_THREAD_DEBUG_IGNORE_EVENT;
				// At any rate we don't need to ignore the signal.
				pendingSignal = -1;
				// send the signal
			}
		} else {
			// there's a signal to send, but no pending signal
			// handle the event
			// ignore the signal
			// send the signal
		}
	} else {
		if (pendingSignal > 0) {
			// there's a pending signal, but no signal to send
			// Ignore the event, if the signal has been sent or will be sent.
			if (thread->signal_status != SIGNAL_FAKED)
				handleEvent = B_THREAD_DEBUG_IGNORE_EVENT;
		} else {
			// there're neither signal to send nor pending signal
			// handle the event
		}
	}

	// ignore the pending signal, if necessary
	if (pendingSignal > 0) {
		debug_nub_set_signal_masks message;
		status_t err;

		message.thread = threadID;
		message.ignore_mask = 0;
		message.ignore_once_mask = B_DEBUG_SIGNAL_TO_MASK(pendingSignal);
		message.ignore_op = B_DEBUG_SIGNAL_MASK_OR;
		message.ignore_once_op = B_DEBUG_SIGNAL_MASK_OR;

		err = haiku_send_debugger_message(teamDebugInfo,
			B_DEBUG_MESSAGE_SET_SIGNAL_MASKS, &message, sizeof(message),
			NULL, 0);
		if (err != B_OK) {
			printf_unfiltered ("Set signal ignore masks for thread %ld: %s\n",
				threadID, strerror(err));
		}
	}

	// send the signal
	if (signalToSend > 0) {
		if (send_signal(threadID, signalToSend) < 0) {
			printf_unfiltered ("Failed to send signal %d to thread %ld: %s\n",
				signalToSend, threadID, strerror(errno));
		}
	}

	// resume thread
	haiku_continue_thread(teamDebugInfo, threadID, handleEvent, step);
	thread->stopped = false;
}
Ejemplo n.º 24
0
char *
handle_line_of_input (struct buffer *cmd_line_buffer,
		      char *rl, int repeat, char *annotation_suffix)
{
  struct ui *ui = current_ui;
  int from_tty = ui->instream == ui->stdin_stream;
  char *p1;
  char *cmd;

  if (rl == NULL)
    return (char *) EOF;

  cmd = command_line_append_input_line (cmd_line_buffer, rl);
  if (cmd == NULL)
    return NULL;

  /* We have a complete command line now.  Prepare for the next
     command, but leave ownership of memory to the buffer .  */
  cmd_line_buffer->used_size = 0;

  if (from_tty && annotation_level > 1)
    {
      printf_unfiltered (("\n\032\032post-"));
      puts_unfiltered (annotation_suffix);
      printf_unfiltered (("\n"));
    }

#define SERVER_COMMAND_PREFIX "server "
  if (startswith (cmd, SERVER_COMMAND_PREFIX))
    {
      /* Note that we don't set `saved_command_line'.  Between this
         and the check in dont_repeat, this insures that repeating
         will still do the right thing.  */
      return cmd + strlen (SERVER_COMMAND_PREFIX);
    }

  /* Do history expansion if that is wished.  */
  if (history_expansion_p && from_tty && input_interactive_p (current_ui))
    {
      char *history_value;
      int expanded;

      expanded = history_expand (cmd, &history_value);
      if (expanded)
	{
	  size_t len;

	  /* Print the changes.  */
	  printf_unfiltered ("%s\n", history_value);

	  /* If there was an error, call this function again.  */
	  if (expanded < 0)
	    {
	      xfree (history_value);
	      return cmd;
	    }

	  /* history_expand returns an allocated string.  Just replace
	     our buffer with it.  */
	  len = strlen (history_value);
	  xfree (buffer_finish (cmd_line_buffer));
	  cmd_line_buffer->buffer = history_value;
	  cmd_line_buffer->buffer_size = len + 1;
	  cmd = history_value;
	}
    }

  /* If we just got an empty line, and that is supposed to repeat the
     previous command, return the previously saved command.  */
  for (p1 = cmd; *p1 == ' ' || *p1 == '\t'; p1++)
    ;
  if (repeat && *p1 == '\0')
    return saved_command_line;

  /* Add command to history if appropriate.  Note: lines consisting
     solely of comments are also added to the command history.  This
     is useful when you type a command, and then realize you don't
     want to execute it quite yet.  You can comment out the command
     and then later fetch it from the value history and remove the
     '#'.  The kill ring is probably better, but some people are in
     the habit of commenting things out.  */
  if (*cmd != '\0' && from_tty && input_interactive_p (current_ui))
    gdb_add_history (cmd);

  /* Save into global buffer if appropriate.  */
  if (repeat)
    {
      xfree (saved_command_line);
      saved_command_line = xstrdup (cmd);
      return saved_command_line;
    }
  else
    return cmd;
}
Ejemplo n.º 25
0
/* FIXME: add comment: */
static void
append_command(const char *cmd, int from_tty)
{
  printf_unfiltered(_("\"append\" must be followed by a subcommand.\n\n"));
  help_list(dump_cmdlist, "append ", (enum command_class)-1, gdb_stdout);
}
Ejemplo n.º 26
0
/* NOTE: 1999-04-30 This is the asynchronous version of the command_loop
   function.  The command_loop function will be obsolete when we
   switch to use the event loop at every execution of gdb. */
static void
command_handler (char *command)
{
  struct cleanup *old_chain;
  int stdin_is_tty = ISATTY (stdin);
  struct continuation_arg *arg1;
  struct continuation_arg *arg2;
  long time_at_cmd_start;
#ifdef HAVE_SBRK
  long space_at_cmd_start = 0;
#endif
  extern int display_time;
  extern int display_space;

  quit_flag = 0;
  if (instream == stdin && stdin_is_tty)
    reinitialize_more_filter ();
  old_chain = make_cleanup (null_cleanup, 0);

  /* If readline returned a NULL command, it means that the 
     connection with the terminal is gone. This happens at the
     end of a testsuite run, after Expect has hung up 
     but GDB is still alive. In such a case, we just quit gdb
     killing the inferior program too. */
  if (command == 0)
    {
      printf_unfiltered ("quit\n");
      execute_command ("quit", stdin == instream);
    }

  time_at_cmd_start = get_run_time ();

  if (display_space)
    {
#ifdef HAVE_SBRK
      char *lim = (char *) sbrk (0);
      space_at_cmd_start = lim - lim_at_start;
#endif
    }

  execute_command (command, instream == stdin);

  /* Set things up for this function to be compete later, once the
     execution has completed, if we are doing an execution command,
     otherwise, just go ahead and finish. */
  if (target_can_async_p () && target_executing)
    {
      arg1 =
	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
      arg2 =
	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
      arg1->next = arg2;
      arg2->next = NULL;
      arg1->data.longint = time_at_cmd_start;
#ifdef HAVE_SBRK
      arg2->data.longint = space_at_cmd_start;
#endif
      add_continuation (command_line_handler_continuation, arg1);
    }

  /* Do any commands attached to breakpoint we stopped at. Only if we
     are always running synchronously. Or if we have just executed a
     command that doesn't start the target. */
  if (!target_can_async_p () || !target_executing)
    {
      bpstat_do_actions (&stop_bpstat);
      do_cleanups (old_chain);

      if (display_time)
	{
	  long cmd_time = get_run_time () - time_at_cmd_start;

	  printf_unfiltered (_("Command execution time: %ld.%06ld\n"),
			     cmd_time / 1000000, cmd_time % 1000000);
	}

      if (display_space)
	{
#ifdef HAVE_SBRK
	  char *lim = (char *) sbrk (0);
	  long space_now = lim - lim_at_start;
	  long space_diff = space_now - space_at_cmd_start;

	  printf_unfiltered (_("Space used: %ld (%c%ld for this command)\n"),
			     space_now,
			     (space_diff >= 0 ? '+' : '-'),
			     space_diff);
#endif
	}
    }
}
Ejemplo n.º 27
0
Archivo: event-top.c Proyecto: 5kg/gdb
/* NOTE: 1999-04-30 This is the asynchronous version of the
   command_line_input function; command_line_input will become
   obsolete once we use the event loop as the default mechanism in
   GDB.  */
static void
command_line_handler (char *rl)
{
  static char *linebuffer = 0;
  static unsigned linelength = 0;
  char *p;
  char *p1;
  char *nline;
  int repeat = (instream == stdin);

  if (annotation_level > 1 && instream == stdin)
    {
      printf_unfiltered (("\n\032\032post-"));
      puts_unfiltered (async_annotation_suffix);
      printf_unfiltered (("\n"));
    }

  if (linebuffer == 0)
    {
      linelength = 80;
      linebuffer = (char *) xmalloc (linelength);
    }

  p = linebuffer;

  if (more_to_come)
    {
      strcpy (linebuffer, readline_input_state.linebuffer);
      p = readline_input_state.linebuffer_ptr;
      xfree (readline_input_state.linebuffer);
      more_to_come = 0;
    }

#ifdef STOP_SIGNAL
  if (job_control)
    signal (STOP_SIGNAL, handle_stop_sig);
#endif

  /* Make sure that all output has been output.  Some machines may let
     you get away with leaving out some of the gdb_flush, but not
     all.  */
  wrap_here ("");
  gdb_flush (gdb_stdout);
  gdb_flush (gdb_stderr);

  if (source_file_name != NULL)
    ++source_line_number;

  /* If we are in this case, then command_handler will call quit 
     and exit from gdb.  */
  if (!rl || rl == (char *) EOF)
    {
      command_handler (0);
      return;			/* Lint.  */
    }
  if (strlen (rl) + 1 + (p - linebuffer) > linelength)
    {
      linelength = strlen (rl) + 1 + (p - linebuffer);
      nline = (char *) xrealloc (linebuffer, linelength);
      p += nline - linebuffer;
      linebuffer = nline;
    }
  p1 = rl;
  /* Copy line.  Don't copy null at end.  (Leaves line alone
     if this was just a newline).  */
  while (*p1)
    *p++ = *p1++;

  xfree (rl);			/* Allocated in readline.  */

  if (p > linebuffer && *(p - 1) == '\\')
    {
      *p = '\0';
      p--;			/* Put on top of '\'.  */

      readline_input_state.linebuffer = xstrdup (linebuffer);
      readline_input_state.linebuffer_ptr = p;

      /* We will not invoke a execute_command if there is more
	 input expected to complete the command.  So, we need to
	 print an empty prompt here.  */
      more_to_come = 1;
      display_gdb_prompt ("");
      return;
    }

#ifdef STOP_SIGNAL
  if (job_control)
    signal (STOP_SIGNAL, SIG_DFL);
#endif

#define SERVER_COMMAND_LENGTH 7
  server_command =
    (p - linebuffer > SERVER_COMMAND_LENGTH)
    && strncmp (linebuffer, "server ", SERVER_COMMAND_LENGTH) == 0;
  if (server_command)
    {
      /* Note that we don't set `line'.  Between this and the check in
         dont_repeat, this insures that repeating will still do the
         right thing.  */
      *p = '\0';
      command_handler (linebuffer + SERVER_COMMAND_LENGTH);
      display_gdb_prompt (0);
      return;
    }

  /* Do history expansion if that is wished.  */
  if (history_expansion_p && instream == stdin
      && ISATTY (instream))
    {
      char *history_value;
      int expanded;

      *p = '\0';		/* Insert null now.  */
      expanded = history_expand (linebuffer, &history_value);
      if (expanded)
	{
	  /* Print the changes.  */
	  printf_unfiltered ("%s\n", history_value);

	  /* If there was an error, call this function again.  */
	  if (expanded < 0)
	    {
	      xfree (history_value);
	      return;
	    }
	  if (strlen (history_value) > linelength)
	    {
	      linelength = strlen (history_value) + 1;
	      linebuffer = (char *) xrealloc (linebuffer, linelength);
	    }
	  strcpy (linebuffer, history_value);
	  p = linebuffer + strlen (linebuffer);
	}
      xfree (history_value);
    }

  /* If we just got an empty line, and that is supposed to repeat the
     previous command, return the value in the global buffer.  */
  if (repeat && p == linebuffer && *p != '\\')
    {
      command_handler (saved_command_line);
      display_gdb_prompt (0);
      return;
    }

  for (p1 = linebuffer; *p1 == ' ' || *p1 == '\t'; p1++);
  if (repeat && !*p1)
    {
      command_handler (saved_command_line);
      display_gdb_prompt (0);
      return;
    }

  *p = 0;

  /* Add line to history if appropriate.  */
  if (instream == stdin
      && ISATTY (stdin) && *linebuffer)
    add_history (linebuffer);

  /* Note: lines consisting solely of comments are added to the command
     history.  This is useful when you type a command, and then
     realize you don't want to execute it quite yet.  You can comment
     out the command and then later fetch it from the value history
     and remove the '#'.  The kill ring is probably better, but some
     people are in the habit of commenting things out.  */
  if (*p1 == '#')
    *p1 = '\0';			/* Found a comment.  */

  /* Save into global buffer if appropriate.  */
  if (repeat)
    {
      if (linelength > saved_command_line_size)
	{
	  saved_command_line = xrealloc (saved_command_line, linelength);
	  saved_command_line_size = linelength;
	}
      strcpy (saved_command_line, linebuffer);
      if (!more_to_come)
	{
	  command_handler (saved_command_line);
	  display_gdb_prompt (0);
	}
      return;
    }

  command_handler (linebuffer);
  display_gdb_prompt (0);
  return;
}
Ejemplo n.º 28
0
void
print_register_hook (int regno)
{
  if (regno == CCR_REGNUM)
    {
      /* CCR register */

      int C, Z, N, V;
      unsigned char b[2];
      unsigned char l;

      frame_register_read (selected_frame, regno, b);
      l = b[1];
      printf_unfiltered ("\t");
      printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
      N = (l & 0x8) != 0;
      Z = (l & 0x4) != 0;
      V = (l & 0x2) != 0;
      C = (l & 0x1) != 0;
      printf_unfiltered ("N-%d ", N);
      printf_unfiltered ("Z-%d ", Z);
      printf_unfiltered ("V-%d ", V);
      printf_unfiltered ("C-%d ", C);
      if ((C | Z) == 0)
	printf_unfiltered ("u> ");
      if ((C | Z) == 1)
	printf_unfiltered ("u<= ");
      if ((C == 0))
	printf_unfiltered ("u>= ");
      if (C == 1)
	printf_unfiltered ("u< ");
      if (Z == 0)
	printf_unfiltered ("!= ");
      if (Z == 1)
	printf_unfiltered ("== ");
      if ((N ^ V) == 0)
	printf_unfiltered (">= ");
      if ((N ^ V) == 1)
	printf_unfiltered ("< ");
      if ((Z | (N ^ V)) == 0)
	printf_unfiltered ("> ");
      if ((Z | (N ^ V)) == 1)
	printf_unfiltered ("<= ");
    }
}
Ejemplo n.º 29
0
static void
detach_thread (ptid_t ptid, int verbose)
{
  if (verbose)
    printf_unfiltered ("[%s exited]\n", target_pid_to_str (ptid));
}
Ejemplo n.º 30
0
static int
captured_main (void *data)
{
  struct captured_main_args *context = data;
  int argc = context->argc;
  char **argv = context->argv;
  int count;
  static int quiet = 0;
  static int batch = 0;
  static int set_args = 0;
  static int already_initialized = 0;

  /* Pointers to various arguments from command line.  */
  char *symarg = NULL;
  char *execarg = NULL;
  char *corearg = NULL;
  char *cdarg = NULL;
  char *ttyarg = NULL;

  /* These are static so that we can take their address in an initializer.  */
  static int print_help;
  static int print_version;

  /* Pointers to all arguments of --command option.  */
  struct cmdarg {
    enum {
      CMDARG_FILE,
      CMDARG_COMMAND
    } type;
    char *string;
  } *cmdarg;
  /* Allocated size of cmdarg.  */
  int cmdsize;
  /* Number of elements of cmdarg used.  */
  int ncmd;

  /* Indices of all arguments of --directory option.  */
  char **dirarg;
  /* Allocated size.  */
  int dirsize;
  /* Number of elements used.  */
  int ndir;

  struct stat homebuf, cwdbuf;
  char *homedir;

  int i;

  long time_at_startup = get_run_time ();

#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
  setlocale (LC_MESSAGES, "");
#endif
#if defined (HAVE_SETLOCALE)
  setlocale (LC_CTYPE, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

#ifdef HAVE_SBRK
  lim_at_start = (char *) sbrk (0);
#endif

#if defined (ALIGN_STACK_ON_STARTUP)
  i = (int) &count & 0x3;
  if (i != 0)
    alloca (4 - i);
#endif

  /* (TiEmu 20050514 Kevin Kofler) Skip all these in case of a restart. */
  cmdsize = 1;
  cmdarg = (struct cmdarg *) xmalloc (cmdsize * sizeof (*cmdarg));
  ncmd = 0;
  dirsize = 1;
  dirarg = (char **) xmalloc (dirsize * sizeof (*dirarg));
  ndir = 0;

  quit_flag = 0;
  line = (char *) xmalloc (linesize);
  line[0] = '\0';		/* Terminate saved (now empty) cmd line */
  if (already_initialized)
    {
      /* (TiEmu 20050512 Kevin Kofler) Reinitialize Insight in case of a restart. */
      gdbtk_started = 0;
      gdbtk_disable_fputs = 1;
    }
  else
  {
  instream = stdin;

  getcwd (gdb_dirbuf, sizeof (gdb_dirbuf));
  current_directory = gdb_dirbuf;

  gdb_stdout = stdio_fileopen (stdout);
  gdb_stderr = stdio_fileopen (stderr);
  gdb_stdlog = gdb_stderr;	/* for moment */
  gdb_stdtarg = gdb_stderr;	/* for moment */
  gdb_stdin = stdio_fileopen (stdin);
  gdb_stdtargerr = gdb_stderr;	/* for moment */
  gdb_stdtargin = gdb_stdin;	/* for moment */

  /* Set the sysroot path.  */
#ifdef TARGET_SYSTEM_ROOT_RELOCATABLE
  gdb_sysroot = make_relative_prefix (argv[0], BINDIR, TARGET_SYSTEM_ROOT);
  if (gdb_sysroot)
    {
      struct stat s;
      int res = 0;

      if (stat (gdb_sysroot, &s) == 0)
	if (S_ISDIR (s.st_mode))
	  res = 1;

      if (res == 0)
	{
	  xfree (gdb_sysroot);
	  gdb_sysroot = TARGET_SYSTEM_ROOT;
	}
    }
  else
    gdb_sysroot = TARGET_SYSTEM_ROOT;
#else
#if defined (TARGET_SYSTEM_ROOT)
  gdb_sysroot = TARGET_SYSTEM_ROOT;
#else
  gdb_sysroot = "";
#endif
#endif

  /* There will always be an interpreter.  Either the one passed into
     this captured main, or one specified by the user at start up, or
     the console.  Initialize the interpreter to the one requested by 
     the application.  */
  interpreter_p = xstrdup (context->interpreter_p);

  /* Parse arguments and options.  */
  {
    int c;
    /* When var field is 0, use flag field to record the equivalent
       short option (or arbitrary numbers starting at 10 for those
       with no equivalent).  */
    enum {
      OPT_SE = 10,
      OPT_CD,
      OPT_ANNOTATE,
      OPT_STATISTICS,
      OPT_TUI,
      OPT_NOWINDOWS,
      OPT_WINDOWS
    };
    static struct option long_options[] =
    {
#if defined(TUI)
      {"tui", no_argument, 0, OPT_TUI},
#endif
      {"xdb", no_argument, &xdb_commands, 1},
      {"dbx", no_argument, &dbx_commands, 1},
      {"readnow", no_argument, &readnow_symbol_files, 1},
      {"r", no_argument, &readnow_symbol_files, 1},
      {"quiet", no_argument, &quiet, 1},
      {"q", no_argument, &quiet, 1},
      {"silent", no_argument, &quiet, 1},
      {"nx", no_argument, &inhibit_gdbinit, 1},
      {"n", no_argument, &inhibit_gdbinit, 1},
      {"batch-silent", no_argument, 0, 'B'},
      {"batch", no_argument, &batch, 1},
      {"epoch", no_argument, &epoch_interface, 1},

    /* This is a synonym for "--annotate=1".  --annotate is now preferred,
       but keep this here for a long time because people will be running
       emacses which use --fullname.  */
      {"fullname", no_argument, 0, 'f'},
      {"f", no_argument, 0, 'f'},

      {"annotate", required_argument, 0, OPT_ANNOTATE},
      {"help", no_argument, &print_help, 1},
      {"se", required_argument, 0, OPT_SE},
      {"symbols", required_argument, 0, 's'},
      {"s", required_argument, 0, 's'},
      {"exec", required_argument, 0, 'e'},
      {"e", required_argument, 0, 'e'},
      {"core", required_argument, 0, 'c'},
      {"c", required_argument, 0, 'c'},
      {"pid", required_argument, 0, 'p'},
      {"p", required_argument, 0, 'p'},
      {"command", required_argument, 0, 'x'},
      {"eval-command", required_argument, 0, 'X'},
      {"version", no_argument, &print_version, 1},
      {"x", required_argument, 0, 'x'},
      {"ex", required_argument, 0, 'X'},
#ifdef GDBTK
      {"tclcommand", required_argument, 0, 'z'},
      {"enable-external-editor", no_argument, 0, 'y'},
      {"editor-command", required_argument, 0, 'w'},
#endif
      {"ui", required_argument, 0, 'i'},
      {"interpreter", required_argument, 0, 'i'},
      {"i", required_argument, 0, 'i'},
      {"directory", required_argument, 0, 'd'},
      {"d", required_argument, 0, 'd'},
      {"cd", required_argument, 0, OPT_CD},
      {"tty", required_argument, 0, 't'},
      {"baud", required_argument, 0, 'b'},
      {"b", required_argument, 0, 'b'},
      {"nw", no_argument, NULL, OPT_NOWINDOWS},
      {"nowindows", no_argument, NULL, OPT_NOWINDOWS},
      {"w", no_argument, NULL, OPT_WINDOWS},
      {"windows", no_argument, NULL, OPT_WINDOWS},
      {"statistics", no_argument, 0, OPT_STATISTICS},
      {"write", no_argument, &write_files, 1},
      {"args", no_argument, &set_args, 1},
     {"l", required_argument, 0, 'l'},
      {"return-child-result", no_argument, &return_child_result, 1},
      {0, no_argument, 0, 0}
    };

    while (1)
      {
	int option_index;

	c = getopt_long_only (argc, argv, "",
			      long_options, &option_index);
	if (c == EOF || set_args)
	  break;

	/* Long option that takes an argument.  */
	if (c == 0 && long_options[option_index].flag == 0)
	  c = long_options[option_index].val;

	switch (c)
	  {
	  case 0:
	    /* Long option that just sets a flag.  */
	    break;
	  case OPT_SE:
	    symarg = optarg;
	    execarg = optarg;
	    break;
	  case OPT_CD:
	    cdarg = optarg;
	    break;
	  case OPT_ANNOTATE:
	    /* FIXME: what if the syntax is wrong (e.g. not digits)?  */
	    annotation_level = atoi (optarg);
	    break;
	  case OPT_STATISTICS:
	    /* Enable the display of both time and space usage.  */
	    display_time = 1;
	    display_space = 1;
	    break;
	  case OPT_TUI:
	    /* --tui is equivalent to -i=tui.  */
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (INTERP_TUI);
	    break;
	  case OPT_WINDOWS:
	    /* FIXME: cagney/2003-03-01: Not sure if this option is
               actually useful, and if it is, what it should do.  */
#ifdef GDBTK
	    /* --windows is equivalent to -i=insight.  */
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (INTERP_INSIGHT);
#endif
	    use_windows = 1;
	    break;
	  case OPT_NOWINDOWS:
	    /* -nw is equivalent to -i=console.  */
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (INTERP_CONSOLE);
	    use_windows = 0;
	    break;
	  case 'f':
	    annotation_level = 1;
/* We have probably been invoked from emacs.  Disable window interface.  */
	    use_windows = 0;
	    break;
	  case 's':
	    symarg = optarg;
	    break;
	  case 'e':
	    execarg = optarg;
	    break;
	  case 'c':
	    corearg = optarg;
	    break;
	  case 'p':
	    /* "corearg" is shared by "--core" and "--pid" */
	    corearg = optarg;
	    break;
	  case 'x':
	    cmdarg[ncmd].type = CMDARG_FILE;
	    cmdarg[ncmd++].string = optarg;
	    if (ncmd >= cmdsize)
	      {
		cmdsize *= 2;
		cmdarg = xrealloc ((char *) cmdarg,
				   cmdsize * sizeof (*cmdarg));
	      }
	    break;
	  case 'X':
	    cmdarg[ncmd].type = CMDARG_COMMAND;
	    cmdarg[ncmd++].string = optarg;
	    if (ncmd >= cmdsize)
	      {
		cmdsize *= 2;
		cmdarg = xrealloc ((char *) cmdarg,
				   cmdsize * sizeof (*cmdarg));
	      }
	    break;
	  case 'B':
	    batch = batch_silent = 1;
	    gdb_stdout = ui_file_new();
	    break;
#ifdef GDBTK
	  case 'z':
	    {
extern int gdbtk_test (char *);
	      if (!gdbtk_test (optarg))
		{
		  fprintf_unfiltered (gdb_stderr, _("%s: unable to load tclcommand file \"%s\""),
				      argv[0], optarg);
		  exit (1);
		}
	      break;
	    }
	  case 'y':
	    /* Backwards compatibility only.  */
	    break;
	  case 'w':
	    {
	      external_editor_command = xstrdup (optarg);
	      break;
	    }
#endif /* GDBTK */
	  case 'i':
	    xfree (interpreter_p);
	    interpreter_p = xstrdup (optarg);
	    break;
	  case 'd':
	    dirarg[ndir++] = optarg;
	    if (ndir >= dirsize)
	      {
		dirsize *= 2;
		dirarg = (char **) xrealloc ((char *) dirarg,
					     dirsize * sizeof (*dirarg));
	      }
	    break;
	  case 't':
	    ttyarg = optarg;
	    break;
	  case 'q':
	    quiet = 1;
	    break;
	  case 'b':
	    {
	      int i;
	      char *p;

	      i = strtol (optarg, &p, 0);
	      if (i == 0 && p == optarg)

		/* Don't use *_filtered or warning() (which relies on
		   current_target) until after initialize_all_files(). */

		fprintf_unfiltered
		  (gdb_stderr,
		   _("warning: could not set baud rate to `%s'.\n"), optarg);
	      else
		baud_rate = i;
	    }
            break;
	  case 'l':
	    {
	      int i;
	      char *p;

	      i = strtol (optarg, &p, 0);
	      if (i == 0 && p == optarg)

		/* Don't use *_filtered or warning() (which relies on
		   current_target) until after initialize_all_files(). */

		fprintf_unfiltered
		  (gdb_stderr,
		 _("warning: could not set timeout limit to `%s'.\n"), optarg);
	      else
		remote_timeout = i;
	    }
	    break;

	  case '?':
	    fprintf_unfiltered (gdb_stderr,
			_("Use `%s --help' for a complete list of options.\n"),
				argv[0]);
	    exit (1);
	  }
      }

    /* If --help or --version, disable window interface.  */
    if (print_help || print_version)
      {
	use_windows = 0;
      }

    if (set_args)
      {
	/* The remaining options are the command-line options for the
	   inferior.  The first one is the sym/exec file, and the rest
	   are arguments.  */
	if (optind >= argc)
	  {
	    fprintf_unfiltered (gdb_stderr,
				_("%s: `--args' specified but no program specified\n"),
				argv[0]);
	    exit (1);
	  }
	symarg = argv[optind];
	execarg = argv[optind];
	++optind;
	set_inferior_args_vector (argc - optind, &argv[optind]);
      }
    else
      {
	/* OK, that's all the options.  The other arguments are filenames.  */
	count = 0;
	for (; optind < argc; optind++)
	  switch (++count)
	    {
	    case 1:
	      symarg = argv[optind];
	      execarg = argv[optind];
	      break;
	    case 2:
	      /* The documentation says this can be a "ProcID" as well. 
	         We will try it as both a corefile and a pid.  */
	      corearg = argv[optind];
	      break;
	    case 3:
	      fprintf_unfiltered (gdb_stderr,
				  _("Excess command line arguments ignored. (%s%s)\n"),
				  argv[optind], (optind == argc - 1) ? "" : " ...");
	      break;
	    }
      }
    if (batch)
      quiet = 1;
  }

  /* Initialize all files.  Give the interpreter a chance to take
     control of the console via the deprecated_init_ui_hook ().  */
  gdb_init (argv[0]);
    already_initialized = 1;
  }

  /* Do these (and anything which might call wrap_here or *_filtered)
     after initialize_all_files() but before the interpreter has been
     installed.  Otherwize the help/version messages will be eaten by
     the interpreter's output handler.  */

  if (print_version)
    {
      print_gdb_version (gdb_stdout);
      wrap_here ("");
      printf_filtered ("\n");
      exit (0);
    }

  if (print_help)
    {
      print_gdb_help (gdb_stdout);
      fputs_unfiltered ("\n", gdb_stdout);
      exit (0);
    }

  /* FIXME: cagney/2003-02-03: The big hack (part 1 of 2) that lets
     GDB retain the old MI1 interpreter startup behavior.  Output the
     copyright message before the interpreter is installed.  That way
     it isn't encapsulated in MI output.  */
  if (!quiet && strcmp (interpreter_p, INTERP_MI1) == 0)
    {
      /* Print all the junk at the top, with trailing "..." if we are about
         to read a symbol file (possibly slowly).  */
      print_gdb_version (gdb_stdout);
      if (symarg)
	printf_filtered ("..");
      wrap_here ("");
      printf_filtered ("\n");
      gdb_flush (gdb_stdout);	/* Force to screen during slow operations */
    }


  /* Install the default UI.  All the interpreters should have had a
     look at things by now.  Initialize the default interpreter. */

  {
    /* Find it.  */
    struct interp *interp = interp_lookup (interpreter_p);
    if (interp == NULL)
      error (_("Interpreter `%s' unrecognized"), interpreter_p);
    /* Install it.  */
    if (!interp_set (interp))
      {
        fprintf_unfiltered (gdb_stderr,
			    "Interpreter `%s' failed to initialize.\n",
                            interpreter_p);
        exit (1);
      }
  }

  /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
     GDB retain the old MI1 interpreter startup behavior.  Output the
     copyright message after the interpreter is installed when it is
     any sane interpreter.  */
  if (!quiet && !current_interp_named_p (INTERP_MI1))
    {
      /* Print all the junk at the top, with trailing "..." if we are about
         to read a symbol file (possibly slowly).  */
      print_gdb_version (gdb_stdout);
      if (symarg)
	printf_filtered ("..");
      wrap_here ("");
      printf_filtered ("\n");
      gdb_flush (gdb_stdout);	/* Force to screen during slow operations */
    }

  /* Set off error and warning messages with a blank line.  */
  error_pre_print = "\n";
  quit_pre_print = error_pre_print;
  warning_pre_print = _("\nwarning: ");

  /* Read and execute $HOME/.gdbinit file, if it exists.  This is done
     *before* all the command line arguments are processed; it sets
     global parameters, which are independent of what file you are
     debugging or what directory you are in.  */
  homedir = getenv ("HOME");
  if (homedir)
    {
      char *homeinit = xstrprintf ("%s/%s", homedir, gdbinit);

      if (!inhibit_gdbinit)
	{
	  catch_command_errors (source_script, homeinit, 0, RETURN_MASK_ALL);
	}

      /* Do stats; no need to do them elsewhere since we'll only
         need them if homedir is set.  Make sure that they are
         zero in case one of them fails (this guarantees that they
         won't match if either exists).  */

      memset (&homebuf, 0, sizeof (struct stat));
      memset (&cwdbuf, 0, sizeof (struct stat));

      stat (homeinit, &homebuf);
      stat (gdbinit, &cwdbuf);	/* We'll only need this if
				   homedir was set.  */
      xfree (homeinit);
    }

  /* Now perform all the actions indicated by the arguments.  */
  if (cdarg != NULL)
    {
      catch_command_errors (cd_command, cdarg, 0, RETURN_MASK_ALL);
    }

  for (i = 0; i < ndir; i++)
    catch_command_errors (directory_switch, dirarg[i], 0, RETURN_MASK_ALL);
  xfree (dirarg);

  if (execarg != NULL
      && symarg != NULL
      && strcmp (execarg, symarg) == 0)
    {
      /* The exec file and the symbol-file are the same.  If we can't
         open it, better only print one error message.
         catch_command_errors returns non-zero on success! */
      if (catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL))
	catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
    }
  else
    {
      if (execarg != NULL)
	catch_command_errors (exec_file_attach, execarg, !batch, RETURN_MASK_ALL);
      if (symarg != NULL)
	catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
    }

  if (corearg != NULL)
    {
      /* corearg may be either a corefile or a pid.
	 If its first character is a digit, try attach first
	 and then corefile.  Otherwise try corefile first. */

      if (isdigit (corearg[0]))
	{
	  if (catch_command_errors (attach_command, corearg, 
				    !batch, RETURN_MASK_ALL) == 0)
	    catch_command_errors (core_file_command, corearg, 
				  !batch, RETURN_MASK_ALL);
	}
      else /* Can't be a pid, better be a corefile. */
	catch_command_errors (core_file_command, corearg, 
			      !batch, RETURN_MASK_ALL);
    }

  if (ttyarg != NULL)
    catch_command_errors (tty_command, ttyarg, !batch, RETURN_MASK_ALL);

  /* Error messages should no longer be distinguished with extra output. */
  error_pre_print = NULL;
  quit_pre_print = NULL;
  warning_pre_print = _("warning: ");

  /* Read the .gdbinit file in the current directory, *if* it isn't
     the same as the $HOME/.gdbinit file (it should exist, also).  */

  if (!homedir
      || memcmp ((char *) &homebuf, (char *) &cwdbuf, sizeof (struct stat)))
    if (!inhibit_gdbinit)
      {
	catch_command_errors (source_script, gdbinit, 0, RETURN_MASK_ALL);
      }

  for (i = 0; i < ncmd; i++)
    {
#if 0
      /* NOTE: cagney/1999-11-03: SET_TOP_LEVEL() was a macro that
         expanded into a call to setjmp().  */
      if (!SET_TOP_LEVEL ()) /* NB: This is #if 0'd out */
	{
	  /* NOTE: I am commenting this out, because it is not clear
	     where this feature is used. It is very old and
	     undocumented. ezannoni: 1999-05-04 */
#if 0
	  if (cmdarg[i][0] == '-' && cmdarg[i][1] == '\0')
	    read_command_file (stdin);
	  else
#endif
	    source_script (cmdarg[i], !batch);
	  do_cleanups (ALL_CLEANUPS);
	}
#endif
      if (cmdarg[i].type == CMDARG_FILE)
        catch_command_errors (source_script, cmdarg[i].string,
			      !batch, RETURN_MASK_ALL);
      else  /* cmdarg[i].type == CMDARG_COMMAND */
        catch_command_errors (execute_command, cmdarg[i].string,
			      !batch, RETURN_MASK_ALL);
    }
  xfree (cmdarg);

  /* Read in the old history after all the command files have been read. */
  init_history ();

  if (batch)
    {
      /* We have hit the end of the batch file.  */
      quit_force (NULL, 0);
    }

  /* Do any host- or target-specific hacks.  This is used for i960 targets
     to force the user to set a nindy target and spec its parameters.  */

#ifdef BEFORE_MAIN_LOOP_HOOK
  BEFORE_MAIN_LOOP_HOOK;
#endif

  /* Show time and/or space usage.  */

  if (display_time)
    {
      long init_time = get_run_time () - time_at_startup;

      printf_unfiltered (_("Startup time: %ld.%06ld\n"),
			 init_time / 1000000, init_time % 1000000);
    }

  if (display_space)
    {
#ifdef HAVE_SBRK
      extern char **environ;
      char *lim = (char *) sbrk (0);

      printf_unfiltered (_("Startup size: data size %ld\n"),
			 (long) (lim - (char *) &environ));
#endif
    }

#if 0
  /* FIXME: cagney/1999-11-06: The original main loop was like: */
  while (1)
    {
      if (!SET_TOP_LEVEL ())
	{
	  do_cleanups (ALL_CLEANUPS);	/* Do complete cleanup */
	  /* GUIs generally have their own command loop, mainloop, or
	     whatever.  This is a good place to gain control because
	     many error conditions will end up here via longjmp().  */
	  if (deprecated_command_loop_hook)
	    deprecated_command_loop_hook ();
	  else
	    deprecated_command_loop ();
	  quit_command ((char *) 0, instream == stdin);
	}
    }
  /* NOTE: If the command_loop() returned normally, the loop would
     attempt to exit by calling the function quit_command().  That
     function would either call exit() or throw an error returning
     control to SET_TOP_LEVEL. */
  /* NOTE: The function do_cleanups() was called once each time round
     the loop.  The usefulness of the call isn't clear.  If an error
     was thrown, everything would have already been cleaned up.  If
     command_loop() returned normally and quit_command() was called,
     either exit() or error() (again cleaning up) would be called. */
#endif
  /* NOTE: cagney/1999-11-07: There is probably no reason for not
     moving this loop and the code found in captured_command_loop()
     into the command_loop() proper.  The main thing holding back that
     change - SET_TOP_LEVEL() - has been eliminated. */
  while (1)
    {
      catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
    }
  /* No exit -- exit is through quit_command.  */
}