aboutsummaryrefslogtreecommitdiff
path: root/gdb/nto-procfs.c
diff options
context:
space:
mode:
authorAleksandar Ristovski <aristovski@qnx.com>2009-07-28 13:20:26 +0000
committerAleksandar Ristovski <aristovski@qnx.com>2009-07-28 13:20:26 +0000
commit745a434e1500a955d8d5d4f0a7173b68d33a764e (patch)
treea7a8f29efe7548321750ef93aebdcd5de3423fa6 /gdb/nto-procfs.c
parent4ad4f3cb145c84f47512dfde2c1ff32be30659fd (diff)
downloadgdb-745a434e1500a955d8d5d4f0a7173b68d33a764e.zip
gdb-745a434e1500a955d8d5d4f0a7173b68d33a764e.tar.gz
gdb-745a434e1500a955d8d5d4f0a7173b68d33a764e.tar.bz2
* nto-tdep.c (nto_thread_state_str): New array.
(nto_extra_thread_info): New function definition. * nto-tdep.h (gdbthread.h): New include. (private_thread_info): New struct. (nto_extra_thread_info): New declaration. * nto-procfs.c (procfs_thread_alive): Properly check if thread is still alive. (update_thread_private_data_name, update_thread_private_data): New function definition. (procfs_find_new_threads): Fetch thread private data. (init_procfs_ops): Register to_extra_thread_info.
Diffstat (limited to 'gdb/nto-procfs.c')
-rw-r--r--gdb/nto-procfs.c117
1 files changed, 108 insertions, 9 deletions
diff --git a/gdb/nto-procfs.c b/gdb/nto-procfs.c
index f724941..0adb045 100644
--- a/gdb/nto-procfs.c
+++ b/gdb/nto-procfs.c
@@ -220,11 +220,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 +318,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;
}
@@ -1338,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