X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fnto-procfs.c;h=3d62ff8a87fad7d7f0063131cf883e3bb25b3d15;hb=71dee6639e9df74c4a4914b4cf19d53266ca9852;hp=8269de18a592bec01c98206287066574681da01e;hpb=c35b149212fc1bf4cf991e42354b0303682bcead;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c index 8269de18a5..3d62ff8a87 100644 --- a/gdb/nto-procfs.c +++ b/gdb/nto-procfs.c @@ -1,7 +1,8 @@ /* Machine independent support for QNX Neutrino /proc (process file system) for GDB. Written by Colin Burgess at QNX Software Systems Limited. - Copyright (C) 2003, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. + Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. Contributed by QNX Software Systems Ltd. @@ -197,7 +198,7 @@ procfs_open (char *arg, int from_tty) { if (sysinfo->type != nto_map_arch_to_cputype (gdbarch_bfd_arch_info - (current_gdbarch)->arch_name)) + (target_gdbarch)->arch_name)) error (_("Invalid target CPU.")); } } @@ -220,11 +221,96 @@ static int procfs_thread_alive (struct target_ops *ops, ptid_t ptid) { pid_t tid; + pid_t pid; + procfs_status status; + int err; tid = ptid_get_tid (ptid); - if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK) - return 1; - return 0; + pid = ptid_get_pid (ptid); + + if (kill (pid, 0) == -1) + return 0; + + status.tid = tid; + if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS, + &status, sizeof (status), 0)) != EOK) + return 0; + + /* Thread is alive or dead but not yet joined, + or dead and there is an alive (or dead unjoined) thread with + higher tid. + + If the tid is not the same as requested, requested tid is dead. */ + return (status.tid == tid) && (status.state != STATE_DEAD); +} + +static void +update_thread_private_data_name (struct thread_info *new_thread, + const char *newname) +{ + int newnamelen; + struct private_thread_info *pti; + + gdb_assert (newname != NULL); + gdb_assert (new_thread != NULL); + newnamelen = strlen (newname); + if (!new_thread->private) + { + new_thread->private = xmalloc (offsetof (struct private_thread_info, + name) + + newnamelen + 1); + memcpy (new_thread->private->name, newname, newnamelen + 1); + } + else if (strcmp (newname, new_thread->private->name) != 0) + { + /* Reallocate if neccessary. */ + int oldnamelen = strlen (new_thread->private->name); + + if (oldnamelen < newnamelen) + new_thread->private = xrealloc (new_thread->private, + offsetof (struct private_thread_info, + name) + + newnamelen + 1); + memcpy (new_thread->private->name, newname, newnamelen + 1); + } +} + +static void +update_thread_private_data (struct thread_info *new_thread, + pthread_t tid, int state, int flags) +{ + struct private_thread_info *pti; + procfs_info pidinfo; + struct _thread_name *tn; + procfs_threadctl tctl; + +#if _NTO_VERSION > 630 + gdb_assert (new_thread != NULL); + + if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo, + sizeof(pidinfo), 0) != EOK) + return; + + memset (&tctl, 0, sizeof (tctl)); + tctl.cmd = _NTO_TCTL_NAME; + tn = (struct _thread_name *) (&tctl.data); + + /* Fetch name for the given thread. */ + tctl.tid = tid; + tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn); + tn->new_name_len = -1; /* Getting, not setting. */ + if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK) + tn->name_buf[0] = '\0'; + + tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0'; + + update_thread_private_data_name (new_thread, tn->name_buf); + + pti = (struct private_thread_info *) new_thread->private; + pti->tid = tid; + pti->state = state; + pti->flags = flags; +#endif /* _NTO_VERSION */ } void @@ -233,20 +319,33 @@ procfs_find_new_threads (struct target_ops *ops) procfs_status status; pid_t pid; ptid_t ptid; + pthread_t tid; + struct thread_info *new_thread; if (ctl_fd == -1) return; pid = ptid_get_pid (inferior_ptid); - for (status.tid = 1;; ++status.tid) + status.tid = 1; + + for (tid = 1;; ++tid) { - if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) - != EOK && status.tid != 0) + if (status.tid == tid + && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) + != EOK)) break; - ptid = ptid_build (pid, 0, status.tid); - if (!in_thread_list (ptid)) - add_thread (ptid); + if (status.tid != tid) + /* The reason why this would not be equal is that devctl might have + returned different tid, meaning the requested tid no longer exists + (e.g. thread exited). */ + continue; + ptid = ptid_build (pid, 0, tid); + new_thread = find_thread_ptid (ptid); + if (!new_thread) + new_thread = add_thread (ptid); + update_thread_private_data (new_thread, tid, status.state, 0); + status.tid++; } return; } @@ -520,10 +619,7 @@ procfs_attach (struct target_ops *ops, char *args, int from_tty) int pid; struct inferior *inf; - if (!args) - error_no_arg (_("process-id to attach")); - - pid = atoi (args); + pid = parse_pid_to_attach (args); if (pid == getpid ()) error (_("Attaching GDB to itself is not a good idea...")); @@ -542,7 +638,8 @@ procfs_attach (struct target_ops *ops, char *args, int from_tty) gdb_flush (gdb_stdout); } inferior_ptid = do_attach (pid_to_ptid (pid)); - inf = add_inferior (pid); + inf = current_inferior (); + inferior_appeared (inf, pid); inf->attach_flag = 1; push_target (ops); @@ -554,7 +651,7 @@ static void procfs_post_attach (pid_t pid) { if (exec_bfd) - solib_create_inferior_hook (); + solib_create_inferior_hook (0); } static ptid_t @@ -824,26 +921,30 @@ procfs_breakpoint (CORE_ADDR addr, int type, int size) } static int -procfs_insert_breakpoint (struct bp_target_info *bp_tgt) +procfs_insert_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0); } static int -procfs_remove_breakpoint (struct bp_target_info *bp_tgt) +procfs_remove_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); } static int -procfs_insert_hw_breakpoint (struct bp_target_info *bp_tgt) +procfs_insert_hw_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); } static int -procfs_remove_hw_breakpoint (struct bp_target_info *bp_tgt) +procfs_remove_hw_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); @@ -1094,7 +1195,8 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file, inferior_ptid = do_attach (pid_to_ptid (pid)); procfs_find_new_threads (ops); - inf = add_inferior (pid); + inf = current_inferior (); + inferior_appeared (inf, pid); inf->attach_flag = 0; flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */ @@ -1110,7 +1212,7 @@ procfs_create_inferior (struct target_ops *ops, char *exec_file, if (exec_bfd != NULL || (symfile_objfile != NULL && symfile_objfile->obfd != NULL)) - solib_create_inferior_hook (); + solib_create_inferior_hook (0); } static void @@ -1334,6 +1436,7 @@ init_procfs_ops (void) procfs_ops.to_has_execution = default_child_has_execution; procfs_ops.to_magic = OPS_MAGIC; procfs_ops.to_have_continuable_watchpoint = 1; + procfs_ops.to_extra_thread_info = nto_extra_thread_info; } #define OSTYPE_NTO 1