summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1998-12-21 07:43:52 +0000
committerDavid Leonard <d@cvs.openbsd.org>1998-12-21 07:43:52 +0000
commitf04b5fd1f20451e24f0bda9e224f47f46a3a55b1 (patch)
tree89b83d6dcb93086c2585a58f15e0081da902cf7f
parentc8c5343c0ee8fb83ece66cc547b716a011aed14c (diff)
much nicer SIGINFO display
-rw-r--r--lib/libc_r/uthread/uthread_info.c297
-rw-r--r--lib/libpthread/uthread/uthread_info.c297
2 files changed, 348 insertions, 246 deletions
diff --git a/lib/libc_r/uthread/uthread_info.c b/lib/libc_r/uthread/uthread_info.c
index 6a863f9463a..f8d7058306b 100644
--- a/lib/libc_r/uthread/uthread_info.c
+++ b/lib/libc_r/uthread/uthread_info.c
@@ -34,10 +34,13 @@
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
+#include <stdlib.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
+extern int _thread_sig_statistics[];
+
struct s_thread_info {
enum pthread_state state;
char *name;
@@ -45,26 +48,41 @@ struct s_thread_info {
/* Static variables: */
static const struct s_thread_info thread_info[] = {
- {PS_RUNNING , "Running"},
- {PS_SIGTHREAD , "Waiting on signal thread"},
- {PS_MUTEX_WAIT , "Waiting on a mutex"},
- {PS_COND_WAIT , "Waiting on a condition variable"},
- {PS_FDLR_WAIT , "Waiting for a file read lock"},
- {PS_FDLW_WAIT , "Waiting for a file write lock"},
- {PS_FDR_WAIT , "Waiting for read"},
- {PS_FDW_WAIT , "Waiting for write"},
- {PS_FILE_WAIT , "Waiting for FILE lock"},
- {PS_SELECT_WAIT , "Waiting on select"},
- {PS_SLEEP_WAIT , "Sleeping"},
- {PS_WAIT_WAIT , "Waiting process"},
- {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
- {PS_SIGWAIT , "Waiting for a signal"},
- {PS_JOIN , "Waiting to join"},
- {PS_SUSPENDED , "Suspended"},
- {PS_DEAD , "Dead"},
- {PS_STATE_MAX , "Not a real state!"}
+ {PS_RUNNING , "running"},
+ {PS_SIGTHREAD , "sigthread"},
+ {PS_MUTEX_WAIT , "mutex_wait"},
+ {PS_COND_WAIT , "cond_wait"},
+ {PS_FDLR_WAIT , "fdlr_wait"},
+ {PS_FDLW_WAIT , "fdlw_wait"},
+ {PS_FDR_WAIT , "fdr_wait"},
+ {PS_FDW_WAIT , "fdw_wait"},
+ {PS_FILE_WAIT , "file_wait"},
+ {PS_SELECT_WAIT , "select_wait"},
+ {PS_SLEEP_WAIT , "sleep_wait"},
+ {PS_WAIT_WAIT , "wait_wait"},
+ {PS_SIGSUSPEND , "sigsuspend"},
+ {PS_SIGWAIT , "sigwait"},
+ {PS_JOIN , "join"},
+ {PS_SUSPENDED , "suspended"},
+ {PS_DEAD , "dead"},
+ {PS_STATE_MAX , "xxx"}
};
+/* Determine a filename for display purposes: */
+static const char *
+truncname(const char *name, int maxlen)
+{
+ int len;
+
+ if (name == NULL)
+ name = "(null)";
+ len = strlen(name);
+ if (len > maxlen)
+ return name + len - maxlen;
+ else
+ return name;
+}
+
void
_thread_dump_info(void)
{
@@ -73,6 +91,7 @@ _thread_dump_info(void)
int i;
int j;
pthread_t pthread;
+ const char *state;
/* Open either the controlling tty or the dump file */
@@ -80,63 +99,80 @@ _thread_dump_info(void)
if (fd < 0)
fd = _thread_sys_open(INFO_DUMP_FILE,
O_WRONLY | O_APPEND | O_CREAT, 0666);
- if (fd >= 0) {
- /* Output a header for active threads: */
- strcpy(s, "\n\n=============\nACTIVE THREADS\n\n");
- _thread_sys_write(fd, s, strlen(s));
+ if (fd < 0)
+ return;
- /* Enter a loop to report each thread in the global list: */
- for (pthread = _thread_link_list; pthread != NULL;
- pthread = pthread->nxt) {
- /* Find the state: */
- for (j = 0; j < (sizeof(thread_info) /
- sizeof(struct s_thread_info)) - 1; j++)
- if (thread_info[j].state == pthread->state)
- break;
- /* Output a record for the current thread: */
- snprintf(s, sizeof(s),
- "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
- pthread, (pthread->name == NULL) ?
- "":pthread->name, pthread->pthread_priority,
- thread_info[j].name,
- pthread->fname,pthread->lineno);
- _thread_sys_write(fd, s, strlen(s));
+ /* Display a list of active threads */
- /* Check if this is the running thread: */
- if (pthread == _thread_run) {
- /* Output a record for the running thread: */
- strcpy(s, "This is the running thread\n");
- _thread_sys_write(fd, s, strlen(s));
- }
- /* Check if this is the initial thread: */
- if (pthread == _thread_initial) {
- /* Output a record for the initial thread: */
- strcpy(s, "This is the initial thread\n");
- _thread_sys_write(fd, s, strlen(s));
- }
- /* Process according to thread state: */
- switch (pthread->state) {
- /* File descriptor read lock wait: */
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FDR_WAIT:
- case PS_FDW_WAIT:
- /* Write the lock details: */
- snprintf(s, sizeof(s), "fd %d[%s:%d]",
- pthread->data.fd.fd,
- pthread->data.fd.fname,
- pthread->data.fd.branch);
- _thread_sys_write(fd, s, strlen(s));
- snprintf(s, sizeof(s), "owner %pr/%pw\n",
- _thread_fd_table[pthread->data.fd.fd]->r_owner,
- _thread_fd_table[pthread->data.fd.fd]->w_owner);
- _thread_sys_write(fd, s, strlen(s));
- break;
- case PS_SIGWAIT:
- snprintf(s, sizeof(s), "sigmask 0x%08lx\n",
- (unsigned long)pthread->sigmask);
- _thread_sys_write(fd, s, strlen(s));
+ snprintf(s, sizeof s, " %8s%c%-11s %2s %4s %-8s %5s %5s %s\n",
+ "id", ' ', "state", "pr", "flag", "name", "utime", "stime",
+ "location");
+ _thread_sys_write(fd, s, strlen(s));
+
+ for (pthread = _thread_link_list; pthread != NULL;
+ pthread = pthread->nxt)
+ {
+ char location[30];
+
+ /* Find last known file:line checkpoint: */
+ if (pthread->fname)
+ snprintf(location, sizeof location, "%s:%d",
+ truncname(pthread->fname, 21), pthread->lineno);
+ else
+ location[0] = '\0';
+
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
break;
+ state = thread_info[j].name;
+
+ /* Output a record for the current thread: */
+ s[0] = 0;
+ snprintf(s, sizeof(s),
+ " %8p%c%-11s %2d %c%c%c%c %-8s %5.2f %5.2f %s\n",
+ (void *)pthread,
+ (pthread == _thread_run) ? '*' : ' ',
+ state,
+ pthread->pthread_priority,
+ (pthread->attr.flags & PTHREAD_DETACHED) ? 'D' : ' ',
+ (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) ? 'S' : ' ',
+ (pthread->attr.flags & PTHREAD_INHERIT_SCHED) ? 'I' : ' ',
+ (pthread->attr.flags & PTHREAD_NOFLOAT) ? 'F' : ' ',
+ (pthread->name == NULL) ? "" : pthread->name,
+ pthread->ru_utime.tv_sec +
+ (double)pthread->ru_utime.tv_usec / 1000000.0,
+ pthread->ru_stime.tv_sec +
+ (double)pthread->ru_stime.tv_usec / 1000000.0,
+ location
+ );
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Process according to thread state: */
+ switch (pthread->state) {
+ /* File descriptor read lock wait: */
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ /* Write the lock details: */
+ snprintf(s, sizeof(s), " - fd %d [%s:%d]\n",
+ pthread->data.fd.fd,
+ truncname(pthread->data.fd.fname, 32),
+ pthread->data.fd.branch);
+ _thread_sys_write(fd, s, strlen(s));
+ s[0] = 0;
+ snprintf(s, sizeof(s), " - owner %pr/%pw\n",
+ _thread_fd_table[pthread->data.fd.fd]->r_owner,
+ _thread_fd_table[pthread->data.fd.fd]->w_owner);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+ case PS_SIGWAIT:
+ snprintf(s, sizeof(s), " - sigmask 0x%08lx\n",
+ (unsigned long)pthread->sigmask);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
/*
* Trap other states that are not explicitly
@@ -145,64 +181,76 @@ _thread_dump_info(void)
default:
/* Nothing to do here. */
break;
- }
}
+ }
- /* Check if there are no dead threads: */
- if (_thread_dead == NULL) {
- /* Output a record: */
- strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
- _thread_sys_write(fd, s, strlen(s));
- } else {
- /* Output a header for dead threads: */
- strcpy(s, "\n\nDEAD THREADS\n\n");
- _thread_sys_write(fd, s, strlen(s));
+ /* Output a header for file descriptors: */
+ snprintf(s, sizeof(s), "file descriptor table, size %d\n",
+ _thread_dtablesize);
+ _thread_sys_write(fd, s, strlen(s));
- /*
- * Enter a loop to report each thread in the global
- * dead thread list:
- */
- for (pthread = _thread_dead; pthread != NULL;
- pthread = pthread->nxt_dead) {
- /* Output a record for the current thread: */
- snprintf(s, sizeof(s),
- "Thread %p prio %3d [%s:%d]\n",
- pthread, pthread->pthread_priority,
- pthread->fname,pthread->lineno);
- _thread_sys_write(fd, s, strlen(s));
- }
- }
+ snprintf(s, sizeof s,
+ " %3s %8s %4s %21s %8s %4s %21s\n",
+ "fd", "rdowner", "rcnt", "rdcode",
+ "wrowner", "wcnt", "wrcode");
+ _thread_sys_write(fd, s, strlen(s));
- /* Output a header for file descriptors: */
- snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR TABLE (table size %d)\n\n",_thread_dtablesize);
- _thread_sys_write(fd, s, strlen(s));
+ /* Enter a loop to report file descriptor lock usage: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /*
+ * Check if memory is allocated for this file
+ * descriptor:
+ */
+ char rcode[22], wcode[22];
- /* Enter a loop to report file descriptor lock usage: */
- for (i = 0; i < _thread_dtablesize; i++) {
- /*
- * Check if memory is allocated for this file
- * descriptor:
- */
- if (_thread_fd_table[i] != NULL) {
- /* Report the file descriptor lock status: */
- snprintf(s, sizeof(s),
- "fd[%3d] read owner %p count %d [%s:%d]\n write owner %p count %d [%s:%d]\n",
- i,
- _thread_fd_table[i]->r_owner,
- _thread_fd_table[i]->r_lockcount,
- _thread_fd_table[i]->r_fname,
- _thread_fd_table[i]->r_lineno,
- _thread_fd_table[i]->w_owner,
- _thread_fd_table[i]->w_lockcount,
- _thread_fd_table[i]->w_fname,
- _thread_fd_table[i]->w_lineno);
- _thread_sys_write(fd, s, strlen(s));
- }
+ if (_thread_fd_table[i] != NULL) {
+
+ /* Find the reader's last file:line: */
+ if (_thread_fd_table[i]->r_owner)
+ snprintf(rcode, sizeof rcode, "%s:%d",
+ truncname(_thread_fd_table[i]->r_fname, 16),
+ _thread_fd_table[i]->r_lineno);
+ else
+ rcode[0] = '\0';
+
+ /* Find the writer's last file:line: */
+ if (_thread_fd_table[i]->w_owner)
+ snprintf(wcode, sizeof wcode, "%s:%d",
+ truncname(_thread_fd_table[i]->w_fname, 16),
+ _thread_fd_table[i]->w_lineno);
+ else
+ wcode[0] = '\0';
+
+ /* Report the file descriptor lock status: */
+ snprintf(s, sizeof(s),
+ " %3d %8p %4d %21s %8p %4d %21s\n",
+ i,
+ _thread_fd_table[i]->r_owner,
+ _thread_fd_table[i]->r_lockcount,
+ rcode,
+ _thread_fd_table[i]->w_owner,
+ _thread_fd_table[i]->w_lockcount,
+ wcode
+ );
+ _thread_sys_write(fd, s, strlen(s));
}
+ }
- /* Close the dump file: */
- _thread_sys_close(fd);
+ /* Show signal counter statistics: */
+ snprintf(s, sizeof s, "sig:");
+ for (i = 0; i < NSIG; i++) {
+ char buf[16] = " xx:xxxxx";
+ if (_thread_sig_statistics[i]) {
+ snprintf(buf, sizeof buf, " %d:%d", i,
+ _thread_sig_statistics[i]);
+ strlcat(s, buf, sizeof s);
+ }
}
+ strlcat(s, "\n", sizeof s);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Close the dump file: */
+ _thread_sys_close(fd);
return;
}
@@ -211,8 +259,11 @@ void
pthread_set_name_np(pthread_t thread, char *name)
{
/* Check if the caller has specified a valid thread: */
- if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+ if (thread != NULL && thread->magic == PTHREAD_MAGIC) {
+ if (thread->name != NULL)
+ free(thread->name);
thread->name = strdup(name);
+ }
return;
}
#endif
diff --git a/lib/libpthread/uthread/uthread_info.c b/lib/libpthread/uthread/uthread_info.c
index 6a863f9463a..f8d7058306b 100644
--- a/lib/libpthread/uthread/uthread_info.c
+++ b/lib/libpthread/uthread/uthread_info.c
@@ -34,10 +34,13 @@
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
+#include <stdlib.h>
#ifdef _THREAD_SAFE
#include <pthread.h>
#include "pthread_private.h"
+extern int _thread_sig_statistics[];
+
struct s_thread_info {
enum pthread_state state;
char *name;
@@ -45,26 +48,41 @@ struct s_thread_info {
/* Static variables: */
static const struct s_thread_info thread_info[] = {
- {PS_RUNNING , "Running"},
- {PS_SIGTHREAD , "Waiting on signal thread"},
- {PS_MUTEX_WAIT , "Waiting on a mutex"},
- {PS_COND_WAIT , "Waiting on a condition variable"},
- {PS_FDLR_WAIT , "Waiting for a file read lock"},
- {PS_FDLW_WAIT , "Waiting for a file write lock"},
- {PS_FDR_WAIT , "Waiting for read"},
- {PS_FDW_WAIT , "Waiting for write"},
- {PS_FILE_WAIT , "Waiting for FILE lock"},
- {PS_SELECT_WAIT , "Waiting on select"},
- {PS_SLEEP_WAIT , "Sleeping"},
- {PS_WAIT_WAIT , "Waiting process"},
- {PS_SIGSUSPEND , "Suspended, waiting for a signal"},
- {PS_SIGWAIT , "Waiting for a signal"},
- {PS_JOIN , "Waiting to join"},
- {PS_SUSPENDED , "Suspended"},
- {PS_DEAD , "Dead"},
- {PS_STATE_MAX , "Not a real state!"}
+ {PS_RUNNING , "running"},
+ {PS_SIGTHREAD , "sigthread"},
+ {PS_MUTEX_WAIT , "mutex_wait"},
+ {PS_COND_WAIT , "cond_wait"},
+ {PS_FDLR_WAIT , "fdlr_wait"},
+ {PS_FDLW_WAIT , "fdlw_wait"},
+ {PS_FDR_WAIT , "fdr_wait"},
+ {PS_FDW_WAIT , "fdw_wait"},
+ {PS_FILE_WAIT , "file_wait"},
+ {PS_SELECT_WAIT , "select_wait"},
+ {PS_SLEEP_WAIT , "sleep_wait"},
+ {PS_WAIT_WAIT , "wait_wait"},
+ {PS_SIGSUSPEND , "sigsuspend"},
+ {PS_SIGWAIT , "sigwait"},
+ {PS_JOIN , "join"},
+ {PS_SUSPENDED , "suspended"},
+ {PS_DEAD , "dead"},
+ {PS_STATE_MAX , "xxx"}
};
+/* Determine a filename for display purposes: */
+static const char *
+truncname(const char *name, int maxlen)
+{
+ int len;
+
+ if (name == NULL)
+ name = "(null)";
+ len = strlen(name);
+ if (len > maxlen)
+ return name + len - maxlen;
+ else
+ return name;
+}
+
void
_thread_dump_info(void)
{
@@ -73,6 +91,7 @@ _thread_dump_info(void)
int i;
int j;
pthread_t pthread;
+ const char *state;
/* Open either the controlling tty or the dump file */
@@ -80,63 +99,80 @@ _thread_dump_info(void)
if (fd < 0)
fd = _thread_sys_open(INFO_DUMP_FILE,
O_WRONLY | O_APPEND | O_CREAT, 0666);
- if (fd >= 0) {
- /* Output a header for active threads: */
- strcpy(s, "\n\n=============\nACTIVE THREADS\n\n");
- _thread_sys_write(fd, s, strlen(s));
+ if (fd < 0)
+ return;
- /* Enter a loop to report each thread in the global list: */
- for (pthread = _thread_link_list; pthread != NULL;
- pthread = pthread->nxt) {
- /* Find the state: */
- for (j = 0; j < (sizeof(thread_info) /
- sizeof(struct s_thread_info)) - 1; j++)
- if (thread_info[j].state == pthread->state)
- break;
- /* Output a record for the current thread: */
- snprintf(s, sizeof(s),
- "--------------------\nThread %p (%s) prio %3d state %s [%s:%d]\n",
- pthread, (pthread->name == NULL) ?
- "":pthread->name, pthread->pthread_priority,
- thread_info[j].name,
- pthread->fname,pthread->lineno);
- _thread_sys_write(fd, s, strlen(s));
+ /* Display a list of active threads */
- /* Check if this is the running thread: */
- if (pthread == _thread_run) {
- /* Output a record for the running thread: */
- strcpy(s, "This is the running thread\n");
- _thread_sys_write(fd, s, strlen(s));
- }
- /* Check if this is the initial thread: */
- if (pthread == _thread_initial) {
- /* Output a record for the initial thread: */
- strcpy(s, "This is the initial thread\n");
- _thread_sys_write(fd, s, strlen(s));
- }
- /* Process according to thread state: */
- switch (pthread->state) {
- /* File descriptor read lock wait: */
- case PS_FDLR_WAIT:
- case PS_FDLW_WAIT:
- case PS_FDR_WAIT:
- case PS_FDW_WAIT:
- /* Write the lock details: */
- snprintf(s, sizeof(s), "fd %d[%s:%d]",
- pthread->data.fd.fd,
- pthread->data.fd.fname,
- pthread->data.fd.branch);
- _thread_sys_write(fd, s, strlen(s));
- snprintf(s, sizeof(s), "owner %pr/%pw\n",
- _thread_fd_table[pthread->data.fd.fd]->r_owner,
- _thread_fd_table[pthread->data.fd.fd]->w_owner);
- _thread_sys_write(fd, s, strlen(s));
- break;
- case PS_SIGWAIT:
- snprintf(s, sizeof(s), "sigmask 0x%08lx\n",
- (unsigned long)pthread->sigmask);
- _thread_sys_write(fd, s, strlen(s));
+ snprintf(s, sizeof s, " %8s%c%-11s %2s %4s %-8s %5s %5s %s\n",
+ "id", ' ', "state", "pr", "flag", "name", "utime", "stime",
+ "location");
+ _thread_sys_write(fd, s, strlen(s));
+
+ for (pthread = _thread_link_list; pthread != NULL;
+ pthread = pthread->nxt)
+ {
+ char location[30];
+
+ /* Find last known file:line checkpoint: */
+ if (pthread->fname)
+ snprintf(location, sizeof location, "%s:%d",
+ truncname(pthread->fname, 21), pthread->lineno);
+ else
+ location[0] = '\0';
+
+ /* Find the state: */
+ for (j = 0; j < (sizeof(thread_info) /
+ sizeof(struct s_thread_info)) - 1; j++)
+ if (thread_info[j].state == pthread->state)
break;
+ state = thread_info[j].name;
+
+ /* Output a record for the current thread: */
+ s[0] = 0;
+ snprintf(s, sizeof(s),
+ " %8p%c%-11s %2d %c%c%c%c %-8s %5.2f %5.2f %s\n",
+ (void *)pthread,
+ (pthread == _thread_run) ? '*' : ' ',
+ state,
+ pthread->pthread_priority,
+ (pthread->attr.flags & PTHREAD_DETACHED) ? 'D' : ' ',
+ (pthread->attr.flags & PTHREAD_SCOPE_SYSTEM) ? 'S' : ' ',
+ (pthread->attr.flags & PTHREAD_INHERIT_SCHED) ? 'I' : ' ',
+ (pthread->attr.flags & PTHREAD_NOFLOAT) ? 'F' : ' ',
+ (pthread->name == NULL) ? "" : pthread->name,
+ pthread->ru_utime.tv_sec +
+ (double)pthread->ru_utime.tv_usec / 1000000.0,
+ pthread->ru_stime.tv_sec +
+ (double)pthread->ru_stime.tv_usec / 1000000.0,
+ location
+ );
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Process according to thread state: */
+ switch (pthread->state) {
+ /* File descriptor read lock wait: */
+ case PS_FDLR_WAIT:
+ case PS_FDLW_WAIT:
+ case PS_FDR_WAIT:
+ case PS_FDW_WAIT:
+ /* Write the lock details: */
+ snprintf(s, sizeof(s), " - fd %d [%s:%d]\n",
+ pthread->data.fd.fd,
+ truncname(pthread->data.fd.fname, 32),
+ pthread->data.fd.branch);
+ _thread_sys_write(fd, s, strlen(s));
+ s[0] = 0;
+ snprintf(s, sizeof(s), " - owner %pr/%pw\n",
+ _thread_fd_table[pthread->data.fd.fd]->r_owner,
+ _thread_fd_table[pthread->data.fd.fd]->w_owner);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
+ case PS_SIGWAIT:
+ snprintf(s, sizeof(s), " - sigmask 0x%08lx\n",
+ (unsigned long)pthread->sigmask);
+ _thread_sys_write(fd, s, strlen(s));
+ break;
/*
* Trap other states that are not explicitly
@@ -145,64 +181,76 @@ _thread_dump_info(void)
default:
/* Nothing to do here. */
break;
- }
}
+ }
- /* Check if there are no dead threads: */
- if (_thread_dead == NULL) {
- /* Output a record: */
- strcpy(s, "\n\nTHERE ARE NO DEAD THREADS\n");
- _thread_sys_write(fd, s, strlen(s));
- } else {
- /* Output a header for dead threads: */
- strcpy(s, "\n\nDEAD THREADS\n\n");
- _thread_sys_write(fd, s, strlen(s));
+ /* Output a header for file descriptors: */
+ snprintf(s, sizeof(s), "file descriptor table, size %d\n",
+ _thread_dtablesize);
+ _thread_sys_write(fd, s, strlen(s));
- /*
- * Enter a loop to report each thread in the global
- * dead thread list:
- */
- for (pthread = _thread_dead; pthread != NULL;
- pthread = pthread->nxt_dead) {
- /* Output a record for the current thread: */
- snprintf(s, sizeof(s),
- "Thread %p prio %3d [%s:%d]\n",
- pthread, pthread->pthread_priority,
- pthread->fname,pthread->lineno);
- _thread_sys_write(fd, s, strlen(s));
- }
- }
+ snprintf(s, sizeof s,
+ " %3s %8s %4s %21s %8s %4s %21s\n",
+ "fd", "rdowner", "rcnt", "rdcode",
+ "wrowner", "wcnt", "wrcode");
+ _thread_sys_write(fd, s, strlen(s));
- /* Output a header for file descriptors: */
- snprintf(s, sizeof(s), "\n\n=============\nFILE DESCRIPTOR TABLE (table size %d)\n\n",_thread_dtablesize);
- _thread_sys_write(fd, s, strlen(s));
+ /* Enter a loop to report file descriptor lock usage: */
+ for (i = 0; i < _thread_dtablesize; i++) {
+ /*
+ * Check if memory is allocated for this file
+ * descriptor:
+ */
+ char rcode[22], wcode[22];
- /* Enter a loop to report file descriptor lock usage: */
- for (i = 0; i < _thread_dtablesize; i++) {
- /*
- * Check if memory is allocated for this file
- * descriptor:
- */
- if (_thread_fd_table[i] != NULL) {
- /* Report the file descriptor lock status: */
- snprintf(s, sizeof(s),
- "fd[%3d] read owner %p count %d [%s:%d]\n write owner %p count %d [%s:%d]\n",
- i,
- _thread_fd_table[i]->r_owner,
- _thread_fd_table[i]->r_lockcount,
- _thread_fd_table[i]->r_fname,
- _thread_fd_table[i]->r_lineno,
- _thread_fd_table[i]->w_owner,
- _thread_fd_table[i]->w_lockcount,
- _thread_fd_table[i]->w_fname,
- _thread_fd_table[i]->w_lineno);
- _thread_sys_write(fd, s, strlen(s));
- }
+ if (_thread_fd_table[i] != NULL) {
+
+ /* Find the reader's last file:line: */
+ if (_thread_fd_table[i]->r_owner)
+ snprintf(rcode, sizeof rcode, "%s:%d",
+ truncname(_thread_fd_table[i]->r_fname, 16),
+ _thread_fd_table[i]->r_lineno);
+ else
+ rcode[0] = '\0';
+
+ /* Find the writer's last file:line: */
+ if (_thread_fd_table[i]->w_owner)
+ snprintf(wcode, sizeof wcode, "%s:%d",
+ truncname(_thread_fd_table[i]->w_fname, 16),
+ _thread_fd_table[i]->w_lineno);
+ else
+ wcode[0] = '\0';
+
+ /* Report the file descriptor lock status: */
+ snprintf(s, sizeof(s),
+ " %3d %8p %4d %21s %8p %4d %21s\n",
+ i,
+ _thread_fd_table[i]->r_owner,
+ _thread_fd_table[i]->r_lockcount,
+ rcode,
+ _thread_fd_table[i]->w_owner,
+ _thread_fd_table[i]->w_lockcount,
+ wcode
+ );
+ _thread_sys_write(fd, s, strlen(s));
}
+ }
- /* Close the dump file: */
- _thread_sys_close(fd);
+ /* Show signal counter statistics: */
+ snprintf(s, sizeof s, "sig:");
+ for (i = 0; i < NSIG; i++) {
+ char buf[16] = " xx:xxxxx";
+ if (_thread_sig_statistics[i]) {
+ snprintf(buf, sizeof buf, " %d:%d", i,
+ _thread_sig_statistics[i]);
+ strlcat(s, buf, sizeof s);
+ }
}
+ strlcat(s, "\n", sizeof s);
+ _thread_sys_write(fd, s, strlen(s));
+
+ /* Close the dump file: */
+ _thread_sys_close(fd);
return;
}
@@ -211,8 +259,11 @@ void
pthread_set_name_np(pthread_t thread, char *name)
{
/* Check if the caller has specified a valid thread: */
- if (thread != NULL && thread->magic == PTHREAD_MAGIC)
+ if (thread != NULL && thread->magic == PTHREAD_MAGIC) {
+ if (thread->name != NULL)
+ free(thread->name);
thread->name = strdup(name);
+ }
return;
}
#endif