* 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.
This commit is contained in:
Aleksandar Ristovski 2009-07-28 13:20:26 +00:00
parent 4ad4f3cb14
commit 745a434e15
4 changed files with 167 additions and 9 deletions

View File

@ -1,3 +1,17 @@
2009-07-28 Aleksandar Ristovski <aristovski@qnx.com>
* 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.
2009-07-25 Pedro Alves <pedro@codesourcery.com>
* stack.c (backtrace_command_1): Remove dead check of NULL current

View File

@ -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

View File

@ -341,6 +341,40 @@ nto_elf_osabi_sniffer (bfd *abfd)
return GDB_OSABI_UNKNOWN;
}
static const char *nto_thread_state_str[] =
{
"DEAD", /* 0 0x00 */
"RUNNING", /* 1 0x01 */
"READY", /* 2 0x02 */
"STOPPED", /* 3 0x03 */
"SEND", /* 4 0x04 */
"RECEIVE", /* 5 0x05 */
"REPLY", /* 6 0x06 */
"STACK", /* 7 0x07 */
"WAITTHREAD", /* 8 0x08 */
"WAITPAGE", /* 9 0x09 */
"SIGSUSPEND", /* 10 0x0a */
"SIGWAITINFO", /* 11 0x0b */
"NANOSLEEP", /* 12 0x0c */
"MUTEX", /* 13 0x0d */
"CONDVAR", /* 14 0x0e */
"JOIN", /* 15 0x0f */
"INTR", /* 16 0x10 */
"SEM", /* 17 0x11 */
"WAITCTX", /* 18 0x12 */
"NET_SEND", /* 19 0x13 */
"NET_REPLY" /* 20 0x14 */
};
char *
nto_extra_thread_info (struct thread_info *ti)
{
if (ti && ti->private
&& ti->private->state < ARRAY_SIZE (nto_thread_state_str))
return (char *)nto_thread_state_str [ti->private->state];
return "";
}
void
nto_initialize_signals (void)
{

View File

@ -25,6 +25,7 @@
#include "solist.h"
#include "osabi.h"
#include "regset.h"
#include "gdbthread.h"
/* Target operations defined for Neutrino targets (<target>-nto-tdep.c). */
@ -138,6 +139,14 @@ typedef struct _debug_regs
qnx_reg64 padding[1024];
} nto_regset_t;
struct private_thread_info
{
short tid;
unsigned char state;
unsigned char flags;
char name[1];
};
/* Generic functions in nto-tdep.c. */
void nto_init_solib_absolute_prefix (void);
@ -162,4 +171,6 @@ void nto_dummy_supply_regset (struct regcache *regcache, char *regs);
int nto_in_dynsym_resolve_code (CORE_ADDR pc);
char *nto_extra_thread_info (struct thread_info *);
#endif