コード例 #1
0
ファイル: lynx-low.c プロジェクト: dcolascione/binutils
static void
lynx_resume (struct thread_resume *resume_info, size_t n)
{
  ptid_t ptid = resume_info[0].thread;
  const int request
    = (resume_info[0].kind == resume_step
       ? (n == 1 ? PTRACE_SINGLESTEP_ONE : PTRACE_SINGLESTEP)
       : PTRACE_CONT);
  const int signal = resume_info[0].sig;

  /* If given a minus_one_ptid, then try using the current_process'
     private->last_wait_event_ptid.  On most LynxOS versions,
     using any of the process' thread works well enough, but
     LynxOS 178 is a little more sensitive, and triggers some
     unexpected signals (Eg SIG61) when we resume the inferior
     using a different thread.  */
  if (ptid_equal (ptid, minus_one_ptid))
    ptid = current_process()->priv->last_wait_event_ptid;

  /* The ptid might still be minus_one_ptid; this can happen between
     the moment we create the inferior or attach to a process, and
     the moment we resume its execution for the first time.  It is
     fine to use the current_thread's ptid in those cases.  */
  if (ptid_equal (ptid, minus_one_ptid))
    ptid = thread_to_gdb_id (current_thread);

  regcache_invalidate ();

  errno = 0;
  lynx_ptrace (request, ptid, 1, signal, 0);
  if (errno)
    perror_with_name ("ptrace");
}
コード例 #2
0
ファイル: ptid.c プロジェクト: Levi-Armstrong/gdb-7.7.1
int
ptid_is_pid (ptid_t ptid)
{
  if (ptid_equal (minus_one_ptid, ptid)
      || ptid_equal (null_ptid, ptid))
    return 0;

  return (ptid_get_lwp (ptid) == 0 && ptid_get_tid (ptid) == 0);
}
コード例 #3
0
ファイル: ptid.c プロジェクト: Levi-Armstrong/gdb-7.7.1
int
ptid_lwp_p (ptid_t ptid)
{
  if (ptid_equal (minus_one_ptid, ptid)
      || ptid_equal (null_ptid, ptid))
    return 0;

  return (ptid_get_lwp (ptid) != 0);
}
コード例 #4
0
ファイル: ptid.c プロジェクト: mbref/binutils-gdb-microblaze
int
ptid_match (ptid_t ptid, ptid_t filter)
{
    if (ptid_equal (filter, minus_one_ptid))
        return 1;
    if (ptid_is_pid (filter)
            && ptid_get_pid (ptid) == ptid_get_pid (filter))
        return 1;
    else if (ptid_equal (ptid, filter))
        return 1;

    return 0;
}
コード例 #5
0
static void
info_mach_exceptions_command (const char *args, int from_tty)
{
  int i;
  task_t task;
  kern_return_t kret;
  darwin_exception_info info;

  info.count = sizeof (info.ports) / sizeof (info.ports[0]);

  if (args != NULL)
    {
      if (strcmp (args, "saved") == 0)
	{
	  if (ptid_equal (inferior_ptid, null_ptid))
	    printf_unfiltered (_("No inferior running\n"));

	  darwin_inferior *priv = get_darwin_inferior (current_inferior ());

	  disp_exception (&priv->exception_info);
	  return;
	}
      else if (strcmp (args, "host") == 0)
	{
	  /* FIXME: This need a privilegied host port!  */
	  kret = host_get_exception_ports
	    (darwin_host_self, EXC_MASK_ALL, info.masks,
	     &info.count, info.ports, info.behaviors, info.flavors);
	  MACH_CHECK_ERROR (kret);
	  disp_exception (&info);
	}
      else
	error (_("Parameter is saved, host or none"));
    }
  else
    {
      struct inferior *inf;

      if (ptid_equal (inferior_ptid, null_ptid))
	printf_unfiltered (_("No inferior running\n"));
      inf = current_inferior ();
      
      darwin_inferior *priv = get_darwin_inferior (inf);

      kret = task_get_exception_ports
	(priv->task, EXC_MASK_ALL, info.masks,
	 &info.count, info.ports, info.behaviors, info.flavors);
      MACH_CHECK_ERROR (kret);
      disp_exception (&info);
    }
}
コード例 #6
0
ファイル: arch-utils.c プロジェクト: jichu4n/prc-tools-remix
/* Generic prepare_to_proceed().  This one should be suitable for most
   targets that support threads. */
int
generic_prepare_to_proceed (int select_it)
{
  ptid_t wait_ptid;
  struct target_waitstatus wait_status;

  /* Get the last target status returned by target_wait().  */
  get_last_target_status (&wait_ptid, &wait_status);

  /* Make sure we were stopped either at a breakpoint, or because
     of a Ctrl-C.  */
  if (wait_status.kind != TARGET_WAITKIND_STOPPED
      || (wait_status.value.sig != TARGET_SIGNAL_TRAP &&
          wait_status.value.sig != TARGET_SIGNAL_INT))
    {
      return 0;
    }

  if (!ptid_equal (wait_ptid, minus_one_ptid)
      && !ptid_equal (inferior_ptid, wait_ptid))
    {
      /* Switched over from WAIT_PID.  */
      CORE_ADDR wait_pc = read_pc_pid (wait_ptid);

      if (wait_pc != read_pc ())
	{
	  if (select_it)
	    {
	      /* Switch back to WAIT_PID thread.  */
	      inferior_ptid = wait_ptid;

	      /* FIXME: This stuff came from switch_to_thread() in
		 thread.c (which should probably be a public function).  */
	      flush_cached_frames ();
	      registers_changed ();
	      stop_pc = wait_pc;
	      select_frame (get_current_frame ());
	    }
          /* We return 1 to indicate that there is a breakpoint here,
             so we need to step over it before continuing to avoid
             hitting it straight away. */
          if (breakpoint_here_p (wait_pc))
            {
	      return 1;
            }
	}
    }
  return 0;
  
}
コード例 #7
0
ファイル: mi-cmd-var.c プロジェクト: ajinkya93/netbsd-src
static void
mi_cmd_var_update_iter (struct varobj *var, void *data_pointer)
{
  struct mi_cmd_var_update *data = data_pointer;
  int thread_id, thread_stopped;

  thread_id = varobj_get_thread_id (var);

  if (thread_id == -1
      && (ptid_equal (inferior_ptid, null_ptid)
	  || is_stopped (inferior_ptid)))
    thread_stopped = 1;
  else
    {
      struct thread_info *tp = find_thread_id (thread_id);

      if (tp)
	thread_stopped = is_stopped (tp->ptid);
      else
	thread_stopped = 1;
    }

  if (thread_stopped
      && (!data->only_floating || varobj_floating_p (var)))
    varobj_update_one (var, data->print_values, 0 /* implicit */);
}
コード例 #8
0
ファイル: nbsd-thread.c プロジェクト: ryo/netbsd-src
static ptid_t
find_active_thread (void)
{
  int val;
  td_thread_t *thread;
  td_thread_info_t ti;
  struct ptrace_lwpinfo pl;

  if (!ptid_equal (cached_thread, minus_one_ptid))
    return cached_thread;

  if (target_has_execution)
    {
      pl.pl_lwpid = 0;
      val = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl));
      while ((val != -1) && (pl.pl_lwpid != 0) &&
	     (pl.pl_event != PL_EVENT_SIGNAL)) {
	val = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl));
    }
      if (pl.pl_lwpid == 0)
	/* found no "active" thread, stay with current */
	pl.pl_lwpid = inferior_ptid.lwp;
    }
  else
    {
      return inferior_ptid;
    }

  cached_thread = ptid_build (ptid_get_pid (main_ptid), pl.pl_lwpid, 0);
  return cached_thread;
}
コード例 #9
0
ファイル: inflow.c プロジェクト: DonCN/haiku
static void
kill_command (char *arg, int from_tty)
{
  /* FIXME:  This should not really be inferior_ptid (or target_has_execution).
     It should be a distinct flag that indicates that a target is active, cuz
     some targets don't have processes! */

  if (ptid_equal (inferior_ptid, null_ptid))
    error ("The program is not being run.");
  if (!query ("Kill the program being debugged? "))
    error ("Not confirmed.");
  target_kill ();

  init_thread_list ();		/* Destroy thread info */

  /* Killing off the inferior can leave us with a core file.  If so,
     print the state we are left in.  */
  if (target_has_stack)
    {
      printf_filtered ("In %s,\n", target_longname);
      if (deprecated_selected_frame == NULL)
	fputs_filtered ("No selected stack frame.\n", gdb_stdout);
      else
	print_stack_frame (get_selected_frame (), 1, SRC_AND_LOC);
    }
  bfd_cache_close_all ();
}
コード例 #10
0
ファイル: nbsd-thread.c プロジェクト: ryo/netbsd-src
static void
nbsd_update_thread_list (struct target_ops *ops)
{
  int retval;
  ptid_t ptid;

  if (nbsd_thread_active == 0)
	  return;

  if (ptid_equal (inferior_ptid, minus_one_ptid))
    {
      printf_filtered ("No process.\n");
      return;
    }

  if (target_has_execution)
    {
      struct ptrace_lwpinfo pl;
      pl.pl_lwpid = 0;
      retval = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl));
      while ((retval != -1) && pl.pl_lwpid != 0)
	{
	  ptid = ptid_build (ptid_get_pid (main_ptid), pl.pl_lwpid, 0);
	  if (!in_thread_list (ptid))
	    add_thread (ptid);
	  retval = ptrace (PT_LWPINFO, ptid_get_pid(inferior_ptid), (void *)&pl, sizeof(pl));
	}
    }
}
コード例 #11
0
ファイル: py-inferior.c プロジェクト: Drakey83/steamlink-sdk
thread_object *
find_thread_object (ptid_t ptid)
{
  int pid;
  struct threadlist_entry *thread;
  PyObject *inf_obj;
  thread_object *found = NULL;

  pid = ptid_get_pid (ptid);
  if (pid == 0)
    return NULL;

  inf_obj = find_inferior_object (pid);

  if (! inf_obj)
    return NULL;

  for (thread = ((inferior_object *)inf_obj)->threads; thread;
       thread = thread->next)
    if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
      {
	found = thread->thread_obj;
	break;
      }

  Py_DECREF (inf_obj);

  if (found)
    return found;

  return NULL;
}
コード例 #12
0
static task_t
get_task_from_args (const char *args)
{
  task_t task;
  char *eptr;

  if (args == NULL || *args == 0)
    {
      if (ptid_equal (inferior_ptid, null_ptid))
	printf_unfiltered (_("No inferior running\n"));

      darwin_inferior *priv = get_darwin_inferior (current_inferior ());

      return priv->task;
    }
  if (strcmp (args, "gdb") == 0)
    return mach_task_self ();
  task = strtoul (args, &eptr, 0);
  if (*eptr)
    {
      printf_unfiltered (_("cannot parse task id '%s'\n"), args);
      return TASK_NULL;
    }
  return task;
}
コード例 #13
0
static int r_debug_qnx_wait (RDebug *dbg, int pid) {
	ptid_t ptid = qnxr_wait (desc, pid);
	if (!ptid_equal (ptid, null_ptid)) {
		dbg->reason.signum = desc->signal;
		return desc->notify_type;
	}
	return 0;
}
コード例 #14
0
ファイル: remote-sim.c プロジェクト: davearrama/gdb
static int
gdbsim_thread_alive (struct target_ops *ops, ptid_t ptid)
{
  if (ptid_equal (ptid, remote_sim_ptid))
    /* The simulators' task is always alive.  */
    return 1;

  return 0;
}
コード例 #15
0
ファイル: record-btrace.c プロジェクト: embecosm/binutils-gdb
static struct thread_info *
record_btrace_find_resume_thread (ptid_t ptid)
{
  struct thread_info *tp;

  /* When asked to resume everything, we pick the current thread.  */
  if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
    ptid = inferior_ptid;

  return find_thread_ptid (ptid);
}
コード例 #16
0
ファイル: dcache.c プロジェクト: AhmadTux/DragonFlyBSD
static void
dcache_info (char *exp, int tty)
{
  splay_tree_node n;
  int i, refcount;

  if (exp)
    {
      char *linestart;

      i = strtol (exp, &linestart, 10);
      if (linestart == exp || i < 0)
	{
	  printf_filtered (_("Usage: info dcache [linenumber]\n"));
          return;
	}

      dcache_print_line (i);
      return;
    }

  printf_filtered (_("Dcache %u lines of %u bytes each.\n"),
		   dcache_size,
		   last_cache ? (unsigned) last_cache->line_size
		   : dcache_line_size);

  if (!last_cache || ptid_equal (last_cache->ptid, null_ptid))
    {
      printf_filtered (_("No data cache available.\n"));
      return;
    }

  printf_filtered (_("Contains data for %s\n"),
		   target_pid_to_str (last_cache->ptid));

  refcount = 0;

  n = splay_tree_min (last_cache->tree);
  i = 0;

  while (n)
    {
      struct dcache_block *db = (struct dcache_block *) n->value;

      printf_filtered (_("Line %d: address %s [%d hits]\n"),
		       i, paddress (target_gdbarch, db->addr), db->refs);
      i++;
      refcount += db->refs;

      n = splay_tree_successor (last_cache->tree, n->key);
    }

  printf_filtered (_("Cache state: %d active lines, %d hits\n"), i, refcount);
}
コード例 #17
0
const char *
target_pid_to_str (ptid_t ptid)
{
  static char buf[80];

  if (ptid_equal (ptid, minus_one_ptid))
    xsnprintf (buf, sizeof (buf), "<all threads>");
  else if (ptid_equal (ptid, null_ptid))
    xsnprintf (buf, sizeof (buf), "<null thread>");
  else if (ptid_get_tid (ptid) != 0)
    xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx",
	       ptid_get_pid (ptid), ptid_get_tid (ptid));
  else if (ptid_get_lwp (ptid) != 0)
    xsnprintf (buf, sizeof (buf), "LWP %d.%ld",
	       ptid_get_pid (ptid), ptid_get_lwp (ptid));
  else
    xsnprintf (buf, sizeof (buf), "Process %d",
	       ptid_get_pid (ptid));

  return buf;
}
コード例 #18
0
static ptid_t
sol_thread_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
  ptid_t rtnval;
  ptid_t save_ptid;
  struct cleanup *old_chain;

  save_ptid = inferior_ptid;
  old_chain = save_inferior_ptid ();

  inferior_ptid = thread_to_lwp (inferior_ptid, PIDGET (main_ph.ptid));
  if (PIDGET (inferior_ptid) == -1)
    inferior_ptid = procfs_first_available ();

  if (PIDGET (ptid) != -1)
    {
      ptid_t save_ptid = ptid;

      ptid = thread_to_lwp (ptid, -2);
      if (PIDGET (ptid) == -2)		/* Inactive thread */
	error ("This version of Solaris can't start inactive threads.");
      if (info_verbose && PIDGET (ptid) == -1)
	warning ("Specified thread %ld seems to have terminated",
		 GET_THREAD (save_ptid));
    }

  rtnval = procfs_ops.to_wait (ptid, ourstatus);

  if (ourstatus->kind != TARGET_WAITKIND_EXITED)
    {
      /* Map the LWP of interest back to the appropriate thread ID */
      rtnval = lwp_to_thread (rtnval);
      if (PIDGET (rtnval) == -1)
	rtnval = save_ptid;

      /* See if we have a new thread */
      if (is_thread (rtnval)
	  && !ptid_equal (rtnval, save_ptid)
	  && !in_thread_list (rtnval))
	{
	  printf_filtered ("[New %s]\n", target_pid_to_str (rtnval));
	  add_thread (rtnval);
	}
    }

  /* During process initialization, we may get here without the thread package
     being initialized, since that can only happen after we've found the shared
     libs.  */

  do_cleanups (old_chain);

  return rtnval;
}
コード例 #19
0
static int
nto_set_thread (ptid_t ptid)
{
  int res = 0;

  TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid),
	 ptid_get_lwp (ptid));
  if (nto_inferior.ctl_fd != -1
      && !ptid_equal (ptid, null_ptid)
      && !ptid_equal (ptid, minus_one_ptid))
    {
      pthread_t tid = ptid_get_lwp (ptid);

      if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid,
	  sizeof (tid), 0))
	res = 1;
      else
	TRACE ("%s: Error: failed to set current thread\n", __func__);
    }
  return res;
}
コード例 #20
0
ファイル: remote-sim.c プロジェクト: davearrama/gdb
static void
gdbsim_resume (struct target_ops *ops,
	       ptid_t ptid, int step, enum target_signal siggnal)
{
  if (!ptid_equal (inferior_ptid, remote_sim_ptid))
    error (_("The program is not being run."));

  if (remote_debug)
    printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal);

  resume_siggnal = siggnal;
  resume_step = step;
}
コード例 #21
0
ファイル: remote-sim.c プロジェクト: davearrama/gdb
static char *
gdbsim_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
  static char buf[64];

  if (ptid_equal (remote_sim_ptid, ptid))
    {
      xsnprintf (buf, sizeof buf, "Thread <main>");
      return buf;
    }

  return normal_pid_to_str (ptid);
}
コード例 #22
0
ファイル: inferiors.c プロジェクト: ajinkya93/netbsd-src
struct inferior_list_entry *
find_inferior_id (struct inferior_list *list, ptid_t id)
{
  struct inferior_list_entry *inf = list->head;

  while (inf != NULL)
    {
      if (ptid_equal (inf->id, id))
	return inf;
      inf = inf->next;
    }

  return NULL;
}
コード例 #23
0
ファイル: inf-loop.c プロジェクト: ChrisG0x20/gdb
void
inferior_event_handler (enum inferior_event_type event_type, 
			gdb_client_data client_data)
{
  switch (event_type)
    {
    case INF_REG_EVENT:
      fetch_inferior_event (client_data);
      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_can_async_p ())
	    target_async (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);

      /* When running a command list (from a user command, say), these
	 are only run when the command list is all done.  */
      if (interpreter_async)
	{
	  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
	    {
	      bpstat_do_actions ();
	    }
	  CATCH (e, RETURN_MASK_ALL)
	    {
	      exception_print (gdb_stderr, e);
	    }
	  END_CATCH
	}
      break;

    default:
      printf_unfiltered (_("Event type not recognized.\n"));
      break;
    }
コード例 #24
0
ptid_t
thread_id_to_gdb_id (ptid_t thread_id)
{
  struct inferior_list_entry *inf = all_threads.head;

  while (inf != NULL)
    {
      if (ptid_equal (inf->id, thread_id))
	return thread_id;
      inf = inf->next;
    }

  return null_ptid;
}
コード例 #25
0
ファイル: dcache.c プロジェクト: AhmadTux/DragonFlyBSD
int
dcache_xfer_memory (struct target_ops *ops, DCACHE *dcache,
		    CORE_ADDR memaddr, gdb_byte *myaddr,
		    int len, int should_write)
{
  int i;
  int res;
  int (*xfunc) (DCACHE *dcache, CORE_ADDR addr, gdb_byte *ptr);

  xfunc = should_write ? dcache_poke_byte : dcache_peek_byte;

  /* If this is a different inferior from what we've recorded,
     flush the cache.  */

  if (! ptid_equal (inferior_ptid, dcache->ptid))
    {
      dcache_invalidate (dcache);
      dcache->ptid = inferior_ptid;
    }

  /* Do write-through first, so that if it fails, we don't write to
     the cache at all.  */

  if (should_write)
    {
      res = target_write (ops, TARGET_OBJECT_RAW_MEMORY,
			  NULL, myaddr, memaddr, len);
      if (res <= 0)
	return res;
      /* Update LEN to what was actually written.  */
      len = res;
    }
      
  for (i = 0; i < len; i++)
    {
      if (!xfunc (dcache, memaddr + i, myaddr + i))
	{
	  /* That failed.  Discard its cache line so we don't have a
	     partially read line.  */
	  dcache_invalidate_line (dcache, memaddr + i);
	  /* If we're writing, we still wrote LEN bytes.  */
	  if (should_write)
	    return len;
	  else
	    return i;
	}
    }
    
  return len;
}
コード例 #26
0
ファイル: mi-interp.c プロジェクト: ajinkya93/netbsd-src
static void
mi_about_to_proceed (void)
{
  /* Suppress output while calling an inferior function.  */

  if (!ptid_equal (inferior_ptid, null_ptid))
    {
      struct thread_info *tp = inferior_thread ();

      if (tp->control.in_infcall)
	return;
    }

  mi_proceeded = 1;
}
コード例 #27
0
struct thread_info *
find_thread_ptid (ptid_t ptid)
{
  struct inferior_list_entry *inf = all_threads.head;

  while (inf != NULL)
    {
      struct thread_info *thread = get_thread (inf);
      if (ptid_equal (thread->entry.id, ptid))
	return thread;
      inf = inf->next;
    }

  return NULL;
}
コード例 #28
0
ファイル: remote-sim.c プロジェクト: davearrama/gdb
static void
gdbsim_create_inferior (struct target_ops *target, char *exec_file, char *args,
			char **env, int from_tty)
{
  int len;
  char *arg_buf, **argv;

  if (exec_file == 0 || exec_bfd == 0)
    warning (_("No executable file specified."));
  if (!program_loaded)
    warning (_("No program loaded."));

  if (remote_debug)
    printf_filtered ("gdbsim_create_inferior: exec_file \"%s\", args \"%s\"\n",
		     (exec_file ? exec_file : "(NULL)"),
		     args);

  if (ptid_equal (inferior_ptid, remote_sim_ptid))
    gdbsim_kill (target);
  remove_breakpoints ();
  init_wait_for_inferior ();

  if (exec_file != NULL)
    {
      len = strlen (exec_file) + 1 + strlen (args) + 1 + /*slop */ 10;
      arg_buf = (char *) alloca (len);
      arg_buf[0] = '\0';
      strcat (arg_buf, exec_file);
      strcat (arg_buf, " ");
      strcat (arg_buf, args);
      argv = gdb_buildargv (arg_buf);
      make_cleanup_freeargv (argv);
    }
  else
    argv = NULL;
  sim_create_inferior (gdbsim_desc, exec_bfd, argv, env);

  inferior_ptid = remote_sim_ptid;
  add_inferior_silent (ptid_get_pid (inferior_ptid));
  add_thread_silent (inferior_ptid);

  target_mark_running (&gdbsim_ops);
  insert_breakpoints ();	/* Needed to get correct instruction in cache */

  clear_proceed_status ();
}
コード例 #29
0
ファイル: py-inferior.c プロジェクト: tkgunji/RCU2_soft
thread_object *
find_thread_object (ptid_t ptid)
{
    int pid;
    struct threadlist_entry *thread;
    PyObject *inf_obj;

    pid = PIDGET (ptid);
    inf_obj = find_inferior_object (pid);

    if (inf_obj)
        for (thread = ((inferior_object *)inf_obj)->threads; thread;
                thread = thread->next)
            if (ptid_equal (thread->thread_obj->thread->ptid, ptid))
                return thread->thread_obj;

    return NULL;
}
コード例 #30
0
ファイル: exec.c プロジェクト: 5432935/crossbridge
void
exec_file_attach (char *filename, int from_tty)
{
  /* Remove any previous exec file.  */
  exec_close ();
  if (!ptid_equal (inferior_ptid, null_ptid))
    {
      target_kill ();
      init_thread_list ();

      struct program_space *ss;
      ALL_PSPACES (ss)
      {
          set_current_program_space (ss);
          breakpoint_program_space_exit (ss);
      }
      symbol_file_clear (0);
    }