Exemplo n.º 1
0
static int
update_registers_callback (struct inferior_list_entry *entry, void *arg)
{
  struct thread_info *thread = (struct thread_info *) entry;
  struct lwp_info *lwp = get_thread_lwp (thread);
  struct update_registers_data *data = (struct update_registers_data *) arg;

  /* Only update the threads of the current process.  */
  if (pid_of (thread) == pid_of (current_thread))
    {
      /* The actual update is done later just before resuming the lwp,
         we just mark that the registers need updating.  */
      if (data->watch)
	lwp->arch_private->wpts_changed[data->i] = 1;
      else
	lwp->arch_private->bpts_changed[data->i] = 1;

      /* If the lwp isn't stopped, force it to momentarily pause, so
         we can update its breakpoint registers.  */
      if (!lwp->stopped)
        linux_stop_lwp (lwp);
    }

  return 0;
}
Exemplo n.º 2
0
static int
attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
{
  struct process_info *proc = current_process ();
  int pid = pid_of (proc);
  ptid_t ptid = ptid_build (pid, ti_p->ti_lid, 0);
  struct lwp_info *lwp;
  int err;

  if (debug_threads)
    debug_printf ("Attaching to thread %ld (LWP %d)\n",
		  (unsigned long) ti_p->ti_tid, ti_p->ti_lid);
  err = linux_attach_lwp (ptid);
  if (err != 0)
    {
      warning ("Could not attach to thread %ld (LWP %d): %s\n",
	       (unsigned long) ti_p->ti_tid, ti_p->ti_lid,
	       linux_ptrace_attach_fail_reason_string (ptid, err));
      return 0;
    }

  lwp = find_lwp_pid (ptid);
  gdb_assert (lwp != NULL);
  lwp->thread_known = 1;
  lwp->th = *th_p;

  return 1;
}
Exemplo n.º 3
0
static void
switch_to_process (struct process_info *proc)
{
  int pid = pid_of (proc);

  current_thread = find_any_thread_of_pid (pid);
}
Exemplo n.º 4
0
static int
aarch64_remove_point (enum raw_bkpt_type type, CORE_ADDR addr,
		      int len, struct raw_breakpoint *bp)
{
  int ret;
  enum target_hw_bp_type targ_type;
  struct aarch64_debug_reg_state *state
    = aarch64_get_debug_reg_state (pid_of (current_thread));

  if (show_debug_regs)
    fprintf (stderr, "remove_point on entry (addr=0x%08lx, len=%d)\n",
	     (unsigned long) addr, len);

  /* Determine the type from the raw breakpoint type.  */
  targ_type = raw_bkpt_type_to_target_hw_bp_type (type);

  /* Set up state pointers.  */
  if (targ_type != hw_execute)
    ret =
      aarch64_handle_watchpoint (targ_type, addr, len, 0 /* is_insert */,
				 state);
  else
    ret =
      aarch64_handle_breakpoint (targ_type, addr, len, 0 /* is_insert */,
				 state);

  if (show_debug_regs)
    aarch64_show_debug_reg_state (state, "remove_point", addr, len,
				  targ_type);

  return ret;
}
Exemplo n.º 5
0
int
thread_db_init (void)
{
  struct process_info *proc = current_process ();

  /* FIXME drow/2004-10-16: This is the "overall process ID", which
     GNU/Linux calls tgid, "thread group ID".  When we support
     attaching to threads, the original thread may not be the correct
     thread.  We would have to get the process ID from /proc for NPTL.

     This isn't the only place in gdbserver that assumes that the first
     process in the list is the thread group leader.  */

  if (thread_db_load_search ())
    {
      /* It's best to avoid td_ta_thr_iter if possible.  That walks
	 data structures in the inferior's address space that may be
	 corrupted, or, if the target is running, the list may change
	 while we walk it.  In the latter case, it's possible that a
	 thread exits just at the exact time that causes GDBserver to
	 get stuck in an infinite loop.  As the kernel supports clone
	 events and /proc/PID/task/ exists, then we already know about
	 all threads in the process.  When we need info out of
	 thread_db on a given thread (e.g., for TLS), we'll use
	 find_one_thread then.  That uses thread_db entry points that
	 do not walk libpthread's thread list, so should be safe, as
	 well as more efficient.  */
      if (!linux_proc_task_list_dir_exists (pid_of (proc)))
	thread_db_find_new_threads ();
      thread_db_look_up_symbols ();
      return 1;
    }

  return 0;
}
Exemplo n.º 6
0
static CORE_ADDR
aarch64_stopped_data_address (void)
{
  siginfo_t siginfo;
  int pid, i;
  struct aarch64_debug_reg_state *state;

  pid = lwpid_of (current_thread);

  /* Get the siginfo.  */
  if (ptrace (PTRACE_GETSIGINFO, pid, NULL, &siginfo) != 0)
    return (CORE_ADDR) 0;

  /* Need to be a hardware breakpoint/watchpoint trap.  */
  if (siginfo.si_signo != SIGTRAP
      || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */)
    return (CORE_ADDR) 0;

  /* Check if the address matches any watched address.  */
  state = aarch64_get_debug_reg_state (pid_of (current_thread));
  for (i = aarch64_num_wp_regs - 1; i >= 0; --i)
    {
      const unsigned int len = aarch64_watchpoint_length (state->dr_ctrl_wp[i]);
      const CORE_ADDR addr_trap = (CORE_ADDR) siginfo.si_addr;
      const CORE_ADDR addr_watch = state->dr_addr_wp[i];
      if (state->dr_ref_count_wp[i]
	  && DR_CONTROL_ENABLED (state->dr_ctrl_wp[i])
	  && addr_trap >= addr_watch
	  && addr_trap < addr_watch + len)
	return addr_trap;
    }

  return (CORE_ADDR) 0;
}
Exemplo n.º 7
0
static void
fbsd_detach_one_process (struct inferior_list_entry *entry)
{
  struct thread_info *thread = (struct thread_info *) entry;
  struct process_info *process = get_thread_process (thread);

  ptrace (PT_DETACH, pid_of (process), 0, 0);
}
static void
x86_dr_low_set_control (unsigned long control)
{
  /* Only update the threads of this process.  */
  int pid = pid_of (current_thread);

  find_inferior (&all_threads, update_debug_registers_callback, &pid);
}
Exemplo n.º 9
0
static void
switch_to_process (struct process_info *proc)
{
  int pid = pid_of (proc);

  current_thread =
    (struct thread_info *) find_inferior (&all_threads,
					  any_thread_of, &pid);
}
Exemplo n.º 10
0
static void
x86_dr_low_set_addr (int regnum, CORE_ADDR addr)
{
  /* Only update the threads of this process.  */
  int pid = pid_of (current_thread);

  gdb_assert (DR_FIRSTADDR <= regnum && regnum <= DR_LASTADDR);

  find_inferior (&all_threads, update_debug_registers_callback, &pid);
}
Exemplo n.º 11
0
static pid_t get_pidof(active_db_h * s)
{
	const char *pidof;

	pidof = get_string(&PIDOF, s);
	if (!pidof)
		return -1;

	return pid_of(pidof);
}
Exemplo n.º 12
0
/* Called when resuming a thread.
   If the debug regs have changed, update the thread's copies.  */
static void
arm_prepare_to_resume (struct lwp_info *lwp)
{
  struct thread_info *thread = get_lwp_thread (lwp);
  int pid = lwpid_of (thread);
  struct process_info *proc = find_process_pid (pid_of (thread));
  struct arch_process_info *proc_info = proc->priv->arch_private;
  struct arch_lwp_info *lwp_info = lwp->arch_private;
  int i;

  for (i = 0; i < arm_linux_get_hw_breakpoint_count (); i++)
    if (lwp_info->bpts_changed[i])
      {
	errno = 0;

	if (arm_hwbp_control_is_enabled (proc_info->bpts[i].control))
	  if (ptrace (PTRACE_SETHBPREGS, pid,
		      (PTRACE_TYPE_ARG3) ((i << 1) + 1),
		      &proc_info->bpts[i].address) < 0)
	    perror_with_name ("Unexpected error setting breakpoint address");

	if (arm_hwbp_control_is_initialized (proc_info->bpts[i].control))
	  if (ptrace (PTRACE_SETHBPREGS, pid,
		      (PTRACE_TYPE_ARG3) ((i << 1) + 2),
		      &proc_info->bpts[i].control) < 0)
	    perror_with_name ("Unexpected error setting breakpoint");

	lwp_info->bpts_changed[i] = 0;
      }

  for (i = 0; i < arm_linux_get_hw_watchpoint_count (); i++)
    if (lwp_info->wpts_changed[i])
      {
	errno = 0;

	if (arm_hwbp_control_is_enabled (proc_info->wpts[i].control))
	  if (ptrace (PTRACE_SETHBPREGS, pid,
		      (PTRACE_TYPE_ARG3) -((i << 1) + 1),
		      &proc_info->wpts[i].address) < 0)
	    perror_with_name ("Unexpected error setting watchpoint address");

	if (arm_hwbp_control_is_initialized (proc_info->wpts[i].control))
	  if (ptrace (PTRACE_SETHBPREGS, pid,
		      (PTRACE_TYPE_ARG3) -((i << 1) + 2),
		      &proc_info->wpts[i].control) < 0)
	    perror_with_name ("Unexpected error setting watchpoint");

	lwp_info->wpts_changed[i] = 0;
      }
}
Exemplo n.º 13
0
void
aarch64_notify_debug_reg_change (const struct aarch64_debug_reg_state *state,
				 int is_watchpoint, unsigned int idx)
{
  struct aarch64_dr_update_callback_param param;

  /* Only update the threads of this process.  */
  param.pid = pid_of (current_thread);

  param.is_watchpoint = is_watchpoint;
  param.idx = idx;

  find_inferior (&all_threads, debug_reg_change_callback, (void *) &param);
}
Exemplo n.º 14
0
static void
fbsd_kill_one_process (struct inferior_list_entry *entry)
{
  struct thread_info *thread = (struct thread_info *) entry;
  struct process_info *process = get_thread_process (thread);
  int wstat;

  do
    {
      ptrace (PT_KILL, pid_of (process), 0, 0);

      /* Make sure it died.  The loop is most likely unnecessary.  */
      wstat = fbsd_wait_for_event (thread);
    } while (WIFSTOPPED (wstat));
}
Exemplo n.º 15
0
static void
tile_arch_setup (void)
{
  int pid = pid_of (current_thread);
  unsigned int machine;
  int is_elf64 = linux_pid_exe_is_elf_64_file (pid, &machine);

  if (sizeof (void *) == 4)
    if (is_elf64 > 0)
      error (_("Can't debug 64-bit process with 32-bit GDBserver"));

  if (!is_elf64)
    current_process ()->tdesc = tdesc_tilegx32;
  else
    current_process ()->tdesc = tdesc_tilegx;
}
Exemplo n.º 16
0
Arquivo: EVENT.C Projeto: jeske/GTalk
void clear_all_old_pids_event(void)
{
  int search, pident;
  struct shared_glm_entry *entry;
  int found;
  int taskno;

  lock_dos(4000);
  search = num_shared;
  while (search>0)
  {
    search--;
    entry = glm_entries[search];
    pident = entry->number_of_tasks;
    while (pident>0)
    {
      pident--;
      found = 0;
      taskno = MAX_THREADS;
      while ((!found) && (taskno>0))
      {
        taskno--;
        if (is_alive(taskno))
         if (entry->pid_list[pident] == pid_of(taskno))
         {
           found = 1;
           break;
         }
      }
      if (!found)
      {
        entry->number_of_tasks--;
        for (taskno=pident;taskno<entry->number_of_tasks;taskno++)
          entry->pid_list[taskno] = entry->pid_list[taskno+1];
      }
    }
    if (!entry->number_of_tasks)
    {
      g_free(entry);
      num_shared--;
      for (taskno=search;taskno<num_shared;taskno++)
        glm_entries[taskno] = glm_entries[taskno+1];
    }
  }
  unlock_dos();
  end_task();
}
Exemplo n.º 17
0
static int
update_debug_registers_callback (struct inferior_list_entry *entry,
				 void *pid_p)
{
  struct thread_info *thr = (struct thread_info *) entry;
  win32_thread_info *th = inferior_target_data (thr);
  int pid = *(int *) pid_p;

  /* Only update the threads of this process.  */
  if (pid_of (thr) == pid)
    {
      /* The actual update is done later just before resuming the lwp,
	 we just mark that the registers need updating.  */
      th->debug_registers_changed = 1;
    }

  return 0;
}
Exemplo n.º 18
0
static void
linux_kill (void)
{
  struct thread_info *thread = (struct thread_info *) all_threads.head;
  struct process_info *process = get_thread_process (thread);
  int wstat;

  for_each_inferior (&all_threads, linux_kill_one_process);

  /* See the comment in linux_kill_one_process.  We did not kill the first
     thread in the list, so do so now.  */
  do
    {
      ptrace (PTRACE_KILL, pid_of (process), 0, 0);

      /* Make sure it died.  The loop is most likely unnecessary.  */
      wstat = linux_wait_for_event (thread);
    } while (WIFSTOPPED (wstat));
}
Exemplo n.º 19
0
static int
attach_thread (const td_thrhandle_t *th_p, td_thrinfo_t *ti_p)
{
  struct process_info *proc = current_process ();
  int pid = pid_of (proc);
  ptid_t ptid = ptid_build (pid, ti_p->ti_lid, 0);
  struct lwp_info *lwp;
  int err;

  if (debug_threads)
    debug_printf ("Attaching to thread %ld (LWP %d)\n",
		  ti_p->ti_tid, ti_p->ti_lid);
  err = linux_attach_lwp (ptid);
  if (err != 0)
    {
      warning ("Could not attach to thread %ld (LWP %d): %s\n",
	       ti_p->ti_tid, ti_p->ti_lid,
	       linux_ptrace_attach_fail_reason_string (ptid, err));
      return 0;
    }

  lwp = find_lwp_pid (ptid);
  gdb_assert (lwp != NULL);
  lwp->thread_known = 1;
  lwp->th = *th_p;

  if (thread_db_use_events)
    {
      td_err_e err;
      struct thread_db *thread_db = proc->priv->thread_db;

      err = thread_db->td_thr_event_enable_p (th_p, 1);
      if (err != TD_OK)
	error ("Cannot enable thread event reporting for %d: %s",
	       ti_p->ti_lid, thread_db_err_str (err));
    }

  return 1;
}
Exemplo n.º 20
0
static void
linux_kill_one_process (struct inferior_list_entry *entry)
{
  struct thread_info *thread = (struct thread_info *) entry;
  struct process_info *process = get_thread_process (thread);
  int wstat;

  /* We avoid killing the first thread here, because of a Linux kernel (at
     least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before
     the children get a chance to be reaped, it will remain a zombie
     forever.  */
  if (entry == all_threads.head)
    return;

  do
    {
      ptrace (PTRACE_KILL, pid_of (process), 0, 0);

      /* Make sure it died.  The loop is most likely unnecessary.  */
      wstat = linux_wait_for_event (thread);
    } while (WIFSTOPPED (wstat));
}
Exemplo n.º 21
0
pid_t
ps_getpid (gdb_ps_prochandle_t ph)
{
  return pid_of (get_thread_lwp (current_inferior));
}
Exemplo n.º 22
0
static void
s390_arch_setup (void)
{
  const struct target_desc *tdesc;
  struct regset_info *regset;

  /* Check whether the kernel supports extra register sets.  */
  int pid = pid_of (get_thread_lwp (current_inferior));
  int have_regset_last_break
    = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
  int have_regset_system_call
    = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
  int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);

  /* Update target_regsets according to available register sets.  */
  for (regset = s390_regsets; regset->fill_function != NULL; regset++)
    if (regset->get_request == PTRACE_GETREGSET)
      switch (regset->nt_type)
	{
	case NT_S390_LAST_BREAK:
	  regset->size = have_regset_last_break? 8 : 0;
	  break;
	case NT_S390_SYSTEM_CALL:
	  regset->size = have_regset_system_call? 4 : 0;
	  break;
	case NT_S390_TDB:
	  regset->size = have_regset_tdb ? 256 : 0;
	default:
	  break;
	}

  /* Assume 31-bit inferior process.  */
  if (have_regset_system_call)
    tdesc = tdesc_s390_linux32v2;
  else if (have_regset_last_break)
    tdesc = tdesc_s390_linux32v1;
  else
    tdesc = tdesc_s390_linux32;

  /* On a 64-bit host, check the low bit of the (31-bit) PSWM
     -- if this is one, we actually have a 64-bit inferior.  */
#ifdef __s390x__
  {
    unsigned int pswm;
    struct regcache *regcache = new_register_cache (tdesc);
    fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
    collect_register_by_name (regcache, "pswm", &pswm);
    free_register_cache (regcache);

    if (pswm & 1)
      {
	if (have_regset_tdb)
	  tdesc = tdesc_s390x_te_linux64;
	if (have_regset_system_call)
	  tdesc = tdesc_s390x_linux64v2;
	else if (have_regset_last_break)
	  tdesc = tdesc_s390x_linux64v1;
	else
	  tdesc = tdesc_s390x_linux64;
      }

    /* For a 31-bit inferior, check whether the kernel supports
       using the full 64-bit GPRs.  */
    else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
      {
	have_hwcap_s390_high_gprs = 1;

	if (have_regset_tdb)
	  tdesc = tdesc_s390_te_linux64;
	else if (have_regset_system_call)
	  tdesc = tdesc_s390_linux64v2;
	else if (have_regset_last_break)
	  tdesc = tdesc_s390_linux64v1;
	else
	  tdesc = tdesc_s390_linux64;
      }
  }
#endif
  current_process ()->tdesc = tdesc;
}
Exemplo n.º 23
0
pid_t
ps_getpid (gdb_ps_prochandle_t ph)
{
  return pid_of (current_inferior);
}
Exemplo n.º 24
0
static int
debug_reg_change_callback (struct inferior_list_entry *entry, void *ptr)
{
  struct thread_info *thread = (struct thread_info *) entry;
  struct lwp_info *lwp = get_thread_lwp (thread);
  struct aarch64_dr_update_callback_param *param_p
    = (struct aarch64_dr_update_callback_param *) ptr;
  int pid = param_p->pid;
  int idx = param_p->idx;
  int is_watchpoint = param_p->is_watchpoint;
  struct arch_lwp_info *info = lwp->arch_private;
  dr_changed_t *dr_changed_ptr;
  dr_changed_t dr_changed;

  if (show_debug_regs)
    {
      fprintf (stderr, "debug_reg_change_callback: \n\tOn entry:\n");
      fprintf (stderr, "\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
	       "dr_changed_wp=0x%llx\n",
	       pid, lwpid_of (thread), info->dr_changed_bp,
	       info->dr_changed_wp);
    }

  dr_changed_ptr = is_watchpoint ? &info->dr_changed_wp
    : &info->dr_changed_bp;
  dr_changed = *dr_changed_ptr;

  /* Only update the threads of this process.  */
  if (pid_of (thread) == pid)
    {
      gdb_assert (idx >= 0
		  && (idx <= (is_watchpoint ? aarch64_num_wp_regs
			      : aarch64_num_bp_regs)));

      /* The following assertion is not right, as there can be changes
	 that have not been made to the hardware debug registers
	 before new changes overwrite the old ones.  This can happen,
	 for instance, when the breakpoint/watchpoint hit one of the
	 threads and the user enters continue; then what happens is:
	 1) all breakpoints/watchpoints are removed for all threads;
	 2) a single step is carried out for the thread that was hit;
	 3) all of the points are inserted again for all threads;
	 4) all threads are resumed.
	 The 2nd step will only affect the one thread in which the
	 bp/wp was hit, which means only that one thread is resumed;
	 remember that the actual updating only happen in
	 aarch64_linux_prepare_to_resume, so other threads remain
	 stopped during the removal and insertion of bp/wp.  Therefore
	 for those threads, the change of insertion of the bp/wp
	 overwrites that of the earlier removals.  (The situation may
	 be different when bp/wp is steppable, or in the non-stop
	 mode.)  */
      /* gdb_assert (DR_N_HAS_CHANGED (dr_changed, idx) == 0);  */

      /* The actual update is done later just before resuming the lwp,
         we just mark that one register pair needs updating.  */
      DR_MARK_N_CHANGED (dr_changed, idx);
      *dr_changed_ptr = dr_changed;

      /* If the lwp isn't stopped, force it to momentarily pause, so
         we can update its debug registers.  */
      if (!lwp->stopped)
	linux_stop_lwp (lwp);
    }

  if (show_debug_regs)
    {
      fprintf (stderr, "\tOn exit:\n\tpid%d, tid: %ld, dr_changed_bp=0x%llx, "
	       "dr_changed_wp=0x%llx\n",
	       pid, lwpid_of (thread), info->dr_changed_bp,
	       info->dr_changed_wp);
    }

  return 0;
}
Exemplo n.º 25
0
static int create_global_segment()
{
    int retval = 0;

    int globalkey = OS_KEY(GLOBAL_KEY, rtapi_instance);
    int rtapikey = OS_KEY(RTAPI_KEY, rtapi_instance);
    int halkey = OS_KEY(HAL_KEY, rtapi_instance);

    int global_exists = shm_common_exists(globalkey);
    int hal_exists = shm_common_exists(halkey);
    int rtapi_exists = shm_common_exists(rtapikey);

    if (global_exists || rtapi_exists || hal_exists) {
	// hm, something is wrong here

	pid_t msgd_pid = pid_of("msgd:%d", rtapi_instance);

	if (rtapi_instance == kernel_instance_id()) {

	    // collision with a running kernel instance - not good.
	    int shmdrv_loaded = is_module_loaded("shmdrv");
	    int rtapi_loaded = is_module_loaded("rtapi");
	    int hal_loaded = is_module_loaded("hal_lib");

	    fprintf(stderr, "ERROR: found existing kernel "
		   "instance with the same instance id (%d)\n",
		   rtapi_instance);

	    fprintf(stderr,"kernel modules loaded: %s%s%s\n",
		   shmdrv_loaded ? "shmdrv " : "",
		   rtapi_loaded ? "rtapi " : "",
		   hal_loaded ? "hal_lib " : "");

	    if (msgd_pid > 0)
		fprintf(stderr,"the msgd process msgd:%d is "
		       "already running, pid: %d\n",
		       rtapi_instance, msgd_pid);
	    else
		fprintf(stderr,"msgd:%d not running!\n",
		       rtapi_instance);
	    return -EEXIST;
	}

	// running userthreads instance?
	pid_t app_pid = pid_of("rtapi:%d", rtapi_instance);

	if ((msgd_pid > -1) || (app_pid > -1)) {

	    fprintf(stderr, "ERROR: found existing user RT "
		   "instance with the same instance id (%d)\n",
		   rtapi_instance);
	    if (msgd_pid > 0)
		fprintf(stderr,"the msgd process msgd:%d is "
		       "already running, pid: %d\n",
		       rtapi_instance, msgd_pid);
	    else
		fprintf(stderr,"msgd:%d not running!\n",
		       rtapi_instance);

	    if (app_pid > 0)
		fprintf(stderr,"the RT process rtapi:%d is "
		       "already running, pid: %d\n",
		       rtapi_instance, app_pid);
	    else
		fprintf(stderr,"the RT process rtapi:%d not running!\n",
		       rtapi_instance);

	    // TBD: might check for other user HAL processes still
	    // around. This might work with fuser on the HAL segment
	    // but might be tricky wit shmdrv.

	    return -EEXIST;
	}

	// leftover shared memory segments were around, but no using
	// entities (user process or kernel modules).
	// Remove and keep going:
	if (shmdrv_loaded) {
	    // since neiter rtapi.ko nor hal_lib.ko is loaded
	    // cause a garbage collect in shmdrv
	    shmdrv_gc();
	} else {
	    // Posix shm case.
	    char segment_name[LINELEN];

	    if (hal_exists) {
		sprintf(segment_name, SHM_FMT, rtapi_instance, halkey);
		fprintf(stderr,"warning: removing unused HAL shm segment %s\n",
			segment_name);
		if (shm_unlink(segment_name))
		    perror(segment_name);
	    }
	    if (rtapi_exists) {
		sprintf(segment_name, SHM_FMT, rtapi_instance, rtapikey);
		fprintf(stderr,"warning: removing unused RTAPI"
			" shm segment %s\n",
			segment_name);
		if (shm_unlink(segment_name))
		    perror(segment_name);
	    }
	    if (global_exists) {
		sprintf(segment_name, SHM_FMT, rtapi_instance, globalkey);
		fprintf(stderr,"warning: removing unused global"
			" shm segment %s\n",
			segment_name);
		if (shm_unlink(segment_name))
		    perror(segment_name);
	    }
	}
    }

    // now try again:
    if (shm_common_exists(globalkey)) {
	fprintf(stderr,
		"MSGD:%d ERROR: found existing global segment key=0x%x\n",
		rtapi_instance, globalkey);

	return -EEXIST;
    }

    int size = sizeof(global_data_t);

    retval = shm_common_new(globalkey, &size,
			    rtapi_instance, (void **) &global_data, 1);
    if (retval < 0) {
	fprintf(stderr,
		"MSGD:%d ERROR: cannot create global segment key=0x%x %s\n",
	       rtapi_instance, globalkey, strerror(-retval));
    }
    if (size != sizeof(global_data_t)) {
	fprintf(stderr,
		"MSGD:%d ERROR: global segment size mismatch: expect %d got %d\n",
	       rtapi_instance, sizeof(global_data_t), size);
	return -EINVAL;
    }
    return retval;
}