diff options
author | David Leonard <d@cvs.openbsd.org> | 1998-12-21 07:43:52 +0000 |
---|---|---|
committer | David Leonard <d@cvs.openbsd.org> | 1998-12-21 07:43:52 +0000 |
commit | f04b5fd1f20451e24f0bda9e224f47f46a3a55b1 (patch) | |
tree | 89b83d6dcb93086c2585a58f15e0081da902cf7f | |
parent | c8c5343c0ee8fb83ece66cc547b716a011aed14c (diff) |
much nicer SIGINFO display
-rw-r--r-- | lib/libc_r/uthread/uthread_info.c | 297 | ||||
-rw-r--r-- | lib/libpthread/uthread/uthread_info.c | 297 |
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 |