summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c4
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/Makefile4
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c99
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d26
-rw-r--r--usr/src/cmd/halt/Makefile5
-rw-r--r--usr/src/cmd/ldapcachemgr/cachemgr_change.c5
-rw-r--r--usr/src/cmd/ldapcachemgr/cachemgr_discovery.c7
-rw-r--r--usr/src/cmd/ldapcachemgr/cachemgr_getldap.c8
-rw-r--r--usr/src/cmd/mdb/common/mdb/mdb_proc.c23
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/findstack.c28
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/genunix.c17
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/thread.c192
-rw-r--r--usr/src/cmd/mdb/common/modules/genunix/thread.h4
-rw-r--r--usr/src/cmd/nscd/cache.c11
-rw-r--r--usr/src/cmd/nscd/nscd_frontend.c13
-rw-r--r--usr/src/cmd/nscd/nscd_getentctx.c9
-rw-r--r--usr/src/cmd/nscd/nscd_selfcred.c7
-rw-r--r--usr/src/cmd/nscd/nscd_smfmonitor.c4
-rw-r--r--usr/src/cmd/prstat/Makefile.com2
-rw-r--r--usr/src/cmd/prstat/prstat.c139
-rw-r--r--usr/src/cmd/prstat/prstat.h5
-rw-r--r--usr/src/cmd/prstat/prutil.c75
-rw-r--r--usr/src/cmd/prstat/prutil.h3
-rw-r--r--usr/src/cmd/ps/ps.c51
-rw-r--r--usr/src/cmd/ptools/pstack/pstack.c66
-rw-r--r--usr/src/cmd/sgs/elfdump/common/corenote.c19
-rw-r--r--usr/src/cmd/sgs/elfdump/common/elfdump.msg3
-rw-r--r--usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c2
-rw-r--r--usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c14
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout.h10
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c9
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c9
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c10
-rw-r--r--usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c9
-rw-r--r--usr/src/cmd/sgs/libconv/Makefile.com6
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.c5
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.msg1
-rw-r--r--usr/src/cmd/svc/startd/graph.c13
-rw-r--r--usr/src/cmd/svc/startd/method.c4
-rw-r--r--usr/src/cmd/svc/startd/restarter.c16
-rw-r--r--usr/src/cmd/svc/startd/wait.c5
41 files changed, 749 insertions, 193 deletions
diff --git a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c
index a5031e9950..c1995611e9 100644
--- a/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c
+++ b/usr/src/cmd/cmd-inet/lib/ipmgmtd/ipmgmt_persist.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
* Copyright 2016 Argo Technologie SA.
* Copyright (c) 2016-2017, Chris Fraire <cfraire@me.com>.
*/
@@ -457,6 +458,7 @@ ipmgmt_db_walk(db_wfunc_t *db_walk_func, void *db_warg, ipadm_db_op_t db_op)
(void) pthread_attr_init(&attr);
(void) pthread_attr_setdetachstate(&attr,
PTHREAD_CREATE_DETACHED);
+ (void) pthread_attr_setname_np(&attr, "db_restore");
err = pthread_create(&tid, &attr, ipmgmt_db_restore_thread,
NULL);
(void) pthread_attr_destroy(&attr);
@@ -1124,7 +1126,7 @@ ipmgmt_aobjmap_init(void *arg, nvlist_t *db_nvl, char *buf, size_t buflen,
{
nvpair_t *nvp = NULL;
char *name, *strval = NULL;
- ipmgmt_aobjmap_t node;
+ ipmgmt_aobjmap_t node;
struct sockaddr_in6 *in6;
*errp = 0;
diff --git a/usr/src/cmd/dtrace/test/tst/common/Makefile b/usr/src/cmd/dtrace/test/tst/common/Makefile
index 808d0e4e8e..a29d774069 100644
--- a/usr/src/cmd/dtrace/test/tst/common/Makefile
+++ b/usr/src/cmd/dtrace/test/tst/common/Makefile
@@ -26,8 +26,8 @@
#
# Copyright (c) 2012 by Delphix. All rights reserved.
-# Copyright (c) 2013, Joyent, Inc. All rights reserved.
# Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+# Copyright 2018 Joyent, Inc.
#
#
@@ -57,6 +57,8 @@ sysevent/tst.post_chan.exe := LDLIBS += -lsysevent
ustack/tst.bigstack.exe := COPTFLAG += -xO1
+CSTD = $(CSTD_GNU99)
+
nfs/%.o: $(SNOOPDIR)/%.c
$(COMPILE.c) -o $@ $< -I$(SNOOPDIR)
$(POST_PROCESS_O)
diff --git a/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c
new file mode 100644
index 0000000000..49d9f2155c
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.c
@@ -0,0 +1,99 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2018 Joyent, Inc.
+ */
+
+/*
+ * All we're doing is constantly modifying a thread name while DTrace is
+ * watching us, making sure we don't break.
+ */
+
+#include <sys/fcntl.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define NR_THREADS (100)
+#define RUNTIME (30) /* seconds */
+
+static void
+random_ascii(char *buf, size_t bufsize)
+{
+ char table[] = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.-#'?!";
+ size_t len = rand() % bufsize;
+
+ bzero(buf, bufsize);
+
+ for (size_t i = 0; i < len; i++) {
+ buf[i] = table[rand() % (sizeof (table) - 1)];
+ }
+}
+
+static void
+busy()
+{
+ struct timeval tv1;
+ struct timeval tv2;
+
+ if (gettimeofday(&tv1, NULL) != 0)
+ abort();
+
+ for (;;) {
+ static volatile int i;
+ for (i = 0; i < 2000000; i++)
+ ;
+
+ if (gettimeofday(&tv2, NULL) != 0)
+ abort();
+
+ /* janky, but we don't care */
+ if (tv2.tv_sec != tv1.tv_sec)
+ return;
+ }
+}
+
+static void *
+thread(void *arg)
+{
+ char name[PTHREAD_MAX_NAMELEN_NP];
+
+ for (size_t i = 0; ; i++) {
+ random_ascii(name, sizeof (name));
+
+ if ((i % 100) == 0) {
+ if (pthread_setname_np(pthread_self(), NULL) != 0)
+ abort();
+ } else {
+ (void) pthread_setname_np(pthread_self(), name);
+ }
+
+ busy();
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ pthread_t tids[NR_THREADS];
+
+ for (size_t i = 0; i < NR_THREADS; i++) {
+ if (pthread_create(&tids[i], NULL, thread, NULL) != 0)
+ exit(EXIT_FAILURE);
+ }
+
+ sleep(RUNTIME);
+ exit(EXIT_SUCCESS);
+}
diff --git a/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d
new file mode 100644
index 0000000000..289f6c5bbc
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/threadname/tst.threadname.d
@@ -0,0 +1,26 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2018 Joyent, Inc.
+ */
+
+#pragma D option quiet
+
+profile-10ms /pid == $1 && threadname == "unlikely"/
+{
+ surprising++;
+}
+
+syscall::rexit:entry /pid == $1/
+{
+ exit(arg0);
+}
diff --git a/usr/src/cmd/halt/Makefile b/usr/src/cmd/halt/Makefile
index 98d8eccee4..a515a0a1ef 100644
--- a/usr/src/cmd/halt/Makefile
+++ b/usr/src/cmd/halt/Makefile
@@ -21,6 +21,7 @@
# Copyright 2016 Toomas Soome <tsoome@me.com>
# Copyright 2010 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2018 Joyent, Inc.
#
PROG = halt
@@ -60,10 +61,10 @@ install := TARGET = install
clean := TARGET = clean
clobber := TARGET = clobber
lint := TARGET = lint
-lint := LINTFLAGS = -u
+lint := LINTFLAGS += -u
-all: $(PROG)
+all: $(PROG)
install: all $(ROOTUSRSBINPROG) $(ROOTLINKS) $(ROOTSYMLINKS) $(SUBDIRS)
diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_change.c b/usr/src/cmd/ldapcachemgr/cachemgr_change.c
index 85a15a1054..727851ffbc 100644
--- a/usr/src/cmd/ldapcachemgr/cachemgr_change.c
+++ b/usr/src/cmd/ldapcachemgr/cachemgr_change.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#include <strings.h>
@@ -33,6 +35,7 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <procfs.h>
+#include <pthread.h>
#include "cachemgr.h"
extern admin_t current_admin;
@@ -535,6 +538,8 @@ chg_cleanup_waiting_threads(void *arg)
pid_t pid;
int always = 1, waiting;
+ (void) pthread_setname_np(pthread_self(), "chg_cleanup_thr");
+
if (op == NULL) {
waiting = 1;
type = CLEANUP_ALL;
diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c b/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c
index bb352ae7c4..6650c9c221 100644
--- a/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c
+++ b/usr/src/cmd/ldapcachemgr/cachemgr_discovery.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#ifdef SLP
@@ -539,9 +541,12 @@ done:
* parameter 'r' should be a pointer to an unsigned int containing
* the requested interval at which the network should be queried.
*/
-void discover(void *r) {
+void
+discover(void *r) {
unsigned short reqrefresh = *((unsigned int *)r);
+ (void) pthread_setname_np(pthread_self(), "discover");
+
for (;;) {
find_all_contexts("ldap",
__cache_get_cfghandle,
diff --git a/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c b/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c
index 298e61fcb0..b9bc3f77b6 100644
--- a/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c
+++ b/usr/src/cmd/ldapcachemgr/cachemgr_getldap.c
@@ -20,6 +20,8 @@
*/
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#include <assert.h>
@@ -1631,6 +1633,8 @@ getldap_serverInfo_op(info_op_t op, char *input, char **output)
static time_t prev_refresh = 0, next_refresh = 0;
ns_server_status_t changed = 0;
+ (void) pthread_setname_np(pthread_self(), "getldap_serverinfo");
+
if (current_admin.debug_level >= DBG_ALL) {
logit("getldap_serverInfo_op()...\n");
}
@@ -2542,6 +2546,8 @@ getldap_refresh()
int sig_done = 0;
int dbg_level;
+ (void) pthread_setname_np(pthread_self(), "getldap_refresh");
+
if (current_admin.debug_level >= DBG_ALL) {
logit("getldap_refresh()...\n");
}
@@ -2892,6 +2898,8 @@ remove_server_thread(void *arg)
int up;
rm_svr_t rms;
+ (void) pthread_setname_np(pthread_self(), "remove_server");
+
up = contact_server(addr);
rms.addr = addr;
diff --git a/usr/src/cmd/mdb/common/mdb/mdb_proc.c b/usr/src/cmd/mdb/common/mdb/mdb_proc.c
index 6c9f0aa5f4..33994c11e6 100644
--- a/usr/src/cmd/mdb/common/mdb/mdb_proc.c
+++ b/usr/src/cmd/mdb/common/mdb/mdb_proc.c
@@ -1303,6 +1303,23 @@ pt_regstatus(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (pt_regs(addr, flags, argc, argv));
}
+static void
+pt_thread_name(mdb_tgt_t *t, mdb_tgt_tid_t tid, char *buf, size_t bufsize)
+{
+ char name[THREAD_NAME_MAX];
+
+ buf[0] = '\0';
+
+ if (t->t_pshandle == NULL ||
+ Plwp_getname(t->t_pshandle, tid, name, sizeof (name)) != 0 ||
+ name[0] == '\0') {
+ (void) mdb_snprintf(buf, bufsize, "%lu", tid);
+ return;
+ }
+
+ (void) mdb_snprintf(buf, bufsize, "%lu [%s]", tid, name);
+}
+
static int
pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
{
@@ -1311,6 +1328,7 @@ pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
int showargs = 0;
int count;
uintptr_t pc, sp;
+ char name[128];
if (!(flags & DCMD_ADDRSPEC))
return (DCMD_USAGE);
@@ -1334,7 +1352,10 @@ pt_findstack(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
#else
sp = gregs.gregs[R_SP];
#endif
- mdb_printf("stack pointer for thread %p: %p\n", tid, sp);
+
+ pt_thread_name(t, tid, name, sizeof (name));
+
+ mdb_printf("stack pointer for thread %s: %p\n", name, sp);
if (pc != 0)
mdb_printf("[ %0?lr %a() ]\n", sp, pc);
diff --git a/usr/src/cmd/mdb/common/modules/genunix/findstack.c b/usr/src/cmd/mdb/common/modules/genunix/findstack.c
index 12b90b8f7d..fc8a4f874b 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/findstack.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/findstack.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
+ * Copyright 2018 Joyent, Inc.
*/
#include <mdb/mdb_modapi.h>
@@ -38,6 +39,12 @@
#include "thread.h"
#include "sobj.h"
+/*
+ * Parts of this file are shared between targets, but this section is only
+ * used for KVM and KMDB.
+ */
+#ifdef _KERNEL
+
int findstack_debug_on = 0;
/*
@@ -48,6 +55,7 @@ print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr,
int argc, const mdb_arg_t *argv, int free_state)
{
int showargs = 0, count, err;
+ char tdesc[128] = "";
count = mdb_getopts(argc, argv,
'v', MDB_OPT_SETBITS, TRUE, &showargs, NULL);
@@ -57,8 +65,10 @@ print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr,
if (argc > 1 || (argc == 1 && argv->a_type != MDB_TYPE_STRING))
return (DCMD_USAGE);
- mdb_printf("stack pointer for thread %p%s: %p\n",
- addr, (free_state ? " (TS_FREE)" : ""), sp);
+ (void) thread_getdesc(addr, B_TRUE, tdesc, sizeof (tdesc));
+
+ mdb_printf("stack pointer for thread %p%s (%s): %p\n",
+ addr, (free_state ? " (TS_FREE)" : ""), tdesc, sp);
if (pc != 0)
mdb_printf("[ %0?lr %a() ]\n", sp, pc);
@@ -108,6 +118,8 @@ findstack_debug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *av)
return (DCMD_OK);
}
+#endif /* _KERNEL */
+
static void
uppercase(char *p)
{
@@ -197,7 +209,7 @@ static stacks_entry_t **stacks_hash;
static stacks_entry_t **stacks_array;
static size_t stacks_array_size;
-size_t
+static size_t
stacks_hash_entry(stacks_entry_t *sep)
{
size_t depth = sep->se_depth;
@@ -224,7 +236,7 @@ stacks_hash_entry(stacks_entry_t *sep)
* relative ordering, so we don't do the extra work of looking up symbols
* for the stack addresses.
*/
-int
+static int
stacks_entry_comp_impl(stacks_entry_t *l, stacks_entry_t *r,
uint_t forsort)
{
@@ -298,7 +310,7 @@ stacks_entry_comp_impl(stacks_entry_t *l, stacks_entry_t *r,
return (0);
}
-int
+static int
stacks_entry_comp(const void *l_arg, const void *r_arg)
{
stacks_entry_t * const *lp = l_arg;
@@ -368,7 +380,7 @@ stacks_cleanup(int force)
}
/*ARGSUSED*/
-int
+static int
stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg)
{
stacks_info_t *sip = cbarg;
@@ -421,7 +433,7 @@ stacks_thread_cb(uintptr_t addr, const void *ignored, void *cbarg)
return (WALK_NEXT);
}
-int
+static int
stacks_run_tlist(mdb_pipe_t *tlist, stacks_info_t *si)
{
size_t idx;
@@ -445,7 +457,7 @@ stacks_run_tlist(mdb_pipe_t *tlist, stacks_info_t *si)
return (-1);
}
-int
+static int
stacks_run(int verbose, mdb_pipe_t *tlist)
{
stacks_info_t si;
diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
index 425911d112..719206065b 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c
@@ -21,7 +21,7 @@
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2017 Joyent, Inc.
+ * Copyright (c) 2018, Joyent, Inc.
* Copyright (c) 2013 by Delphix. All rights reserved.
*/
@@ -164,14 +164,19 @@ ps_threadprint(uintptr_t addr, const void *data, void *private)
if (prt_flags & PS_PRTTHREADS)
mdb_printf("\tT %?a <%b>\n", addr, t->t_state, t_state_bits);
- if (prt_flags & PS_PRTLWPS)
- mdb_printf("\tL %?a ID: %u\n", t->t_lwp, t->t_tid);
+ if (prt_flags & PS_PRTLWPS) {
+ char desc[128] = "";
+
+ (void) thread_getdesc(addr, B_FALSE, desc, sizeof (desc));
+
+ mdb_printf("\tL %?a ID: %s\n", t->t_lwp, desc);
+ }
return (WALK_NEXT);
}
typedef struct mdb_pflags_proc {
- struct pid *p_pidp;
+ struct pid *p_pidp;
ushort_t p_pidflag;
uint_t p_proc_flag;
uint_t p_flag;
@@ -261,8 +266,8 @@ pflags(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
typedef struct mdb_ps_proc {
char p_stat;
- struct pid *p_pidp;
- struct pid *p_pgidp;
+ struct pid *p_pidp;
+ struct pid *p_pgidp;
struct cred *p_cred;
struct sess *p_sessp;
struct task *p_task;
diff --git a/usr/src/cmd/mdb/common/modules/genunix/thread.c b/usr/src/cmd/mdb/common/modules/genunix/thread.c
index 652e5af2d6..410f9973d8 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/thread.c
+++ b/usr/src/cmd/mdb/common/modules/genunix/thread.c
@@ -24,11 +24,13 @@
*/
/*
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
*/
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_ks.h>
+#include <mdb/mdb_ctf.h>
#include <sys/types.h>
#include <sys/thread.h>
#include <sys/lwp.h>
@@ -38,6 +40,7 @@
#include <sys/disp.h>
#include <sys/taskq_impl.h>
#include <sys/stack.h>
+#include "thread.h"
#ifndef STACK_BIAS
#define STACK_BIAS 0
@@ -561,6 +564,89 @@ thread_help(void)
}
/*
+ * Return a string description of the thread, including the ID and the thread
+ * name.
+ *
+ * If ->t_name is NULL, and we're a system thread, we'll do a little more
+ * spelunking to find a useful string to return.
+ */
+int
+thread_getdesc(uintptr_t addr, boolean_t include_comm,
+ char *buf, size_t bufsize)
+{
+ char name[THREAD_NAME_MAX] = "";
+ kthread_t t;
+ proc_t p;
+
+ bzero(buf, bufsize);
+
+ if (mdb_vread(&t, sizeof (kthread_t), addr) == -1) {
+ mdb_warn("failed to read kthread_t at %p", addr);
+ return (-1);
+ }
+
+ if (t.t_tid == 0) {
+ taskq_t tq;
+
+ if (mdb_vread(&tq, sizeof (taskq_t),
+ (uintptr_t)t.t_taskq) == -1)
+ tq.tq_name[0] = '\0';
+
+ if (t.t_name != NULL) {
+ if (mdb_readstr(buf, bufsize,
+ (uintptr_t)t.t_name) == -1) {
+ mdb_warn("error reading thread name");
+ }
+ } else if (tq.tq_name[0] != '\0') {
+ (void) mdb_snprintf(buf, bufsize, "tq:%s", tq.tq_name);
+ } else {
+ mdb_snprintf(buf, bufsize, "%a()", t.t_startpc);
+ }
+
+ return (buf[0] == '\0' ? -1 : 0);
+ }
+
+ if (include_comm && mdb_vread(&p, sizeof (proc_t),
+ (uintptr_t)t.t_procp) == -1) {
+ mdb_warn("failed to read proc at %p", t.t_procp);
+ return (-1);
+ }
+
+ if (t.t_name != NULL) {
+ if (mdb_readstr(name, sizeof (name), (uintptr_t)t.t_name) == -1)
+ mdb_warn("error reading thread name");
+
+ /*
+ * Just to be safe -- if mdb_readstr() succeeds, it always NUL
+ * terminates the output, but is unclear what it does on
+ * failure. In that case we attempt to show any partial content
+ * w/ the warning in case it's useful, but explicitly
+ * NUL-terminate to be safe.
+ */
+ buf[bufsize - 1] = '\0';
+ }
+
+ if (name[0] != '\0') {
+ if (include_comm) {
+ (void) mdb_snprintf(buf, bufsize, "%s/%u [%s]",
+ p.p_user.u_comm, t.t_tid, name);
+ } else {
+ (void) mdb_snprintf(buf, bufsize, "%u [%s]",
+ t.t_tid, name);
+ }
+ } else {
+ if (include_comm) {
+ (void) mdb_snprintf(buf, bufsize, "%s/%u",
+ p.p_user.u_comm, t.t_tid);
+ } else {
+ (void) mdb_snprintf(buf, bufsize, "%u", t.t_tid);
+ }
+ }
+
+ return (buf[0] == '\0' ? -1 : 0);
+}
+
+/*
* List a combination of kthread_t and proc_t. Add stack traces in verbose mode.
*/
int
@@ -571,8 +657,6 @@ threadlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
uint_t verbose = FALSE;
uint_t notaskq = FALSE;
kthread_t t;
- taskq_t tq;
- proc_t p;
char cmd[80];
mdb_arg_t cmdarg;
@@ -618,50 +702,32 @@ threadlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if (t.t_state == TS_FREE)
return (DCMD_OK);
- if (mdb_vread(&p, sizeof (proc_t), (uintptr_t)t.t_procp) == -1) {
- mdb_warn("failed to read proc at %p", t.t_procp);
- return (DCMD_ERR);
- }
+ if (!verbose) {
+ char desc[128];
+
+ if (thread_getdesc(addr, B_TRUE, desc, sizeof (desc)) == -1)
+ return (DCMD_ERR);
- if (mdb_vread(&tq, sizeof (taskq_t), (uintptr_t)t.t_taskq) == -1)
- tq.tq_name[0] = '\0';
+ mdb_printf("%0?p %?p %?p %s\n", addr, t.t_procp, t.t_lwp, desc);
+ return (DCMD_OK);
+ }
- if (verbose) {
- mdb_printf("%0?p %?p %?p %3u %3d %?p\n",
- addr, t.t_procp, t.t_lwp, t.t_cid, t.t_pri, t.t_wchan);
+ mdb_printf("%0?p %?p %?p %3u %3d %?p\n",
+ addr, t.t_procp, t.t_lwp, t.t_cid, t.t_pri, t.t_wchan);
- mdb_inc_indent(2);
+ mdb_inc_indent(2);
- mdb_printf("PC: %a", t.t_pc);
- if (t.t_tid == 0) {
- if (tq.tq_name[0] != '\0')
- mdb_printf(" TASKQ: %s\n", tq.tq_name);
- else
- mdb_printf(" THREAD: %a()\n", t.t_startpc);
- } else {
- mdb_printf(" CMD: %s\n", p.p_user.u_psargs);
- }
+ mdb_printf("PC: %a\n", t.t_pc);
- mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", count);
- cmdarg.a_type = MDB_TYPE_STRING;
- cmdarg.a_un.a_str = cmd;
+ mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", count);
+ cmdarg.a_type = MDB_TYPE_STRING;
+ cmdarg.a_un.a_str = cmd;
- (void) mdb_call_dcmd("findstack", addr, flags, 1, &cmdarg);
+ (void) mdb_call_dcmd("findstack", addr, flags, 1, &cmdarg);
- mdb_dec_indent(2);
+ mdb_dec_indent(2);
- mdb_printf("\n");
- } else {
- mdb_printf("%0?p %?p %?p", addr, t.t_procp, t.t_lwp);
- if (t.t_tid == 0) {
- if (tq.tq_name[0] != '\0')
- mdb_printf(" tq:%s\n", tq.tq_name);
- else
- mdb_printf(" %a()\n", t.t_startpc);
- } else {
- mdb_printf(" %s/%u\n", p.p_user.u_comm, t.t_tid);
- }
- }
+ mdb_printf("\n");
return (DCMD_OK);
}
@@ -716,7 +782,6 @@ int
stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
{
kthread_t t;
- proc_t p;
uint64_t *ptr; /* pattern pointer */
caddr_t start; /* kernel stack start */
caddr_t end; /* kernel stack end */
@@ -730,6 +795,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
int i = 0;
unsigned int ukmem_stackinfo;
uintptr_t allthreads;
+ char tdesc[128] = "";
/* handle options */
if (mdb_getopts(argc, argv,
@@ -775,7 +841,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf("%<u>%?s%</u>", "THREAD");
mdb_printf(" %<u>%?s%</u>", "STACK");
- mdb_printf("%<u>%s%</u>", " SIZE MAX CMD/LWPID or STARTPC");
+ mdb_printf("%<u>%s%</u>", " SIZE MAX LWP");
mdb_printf("\n");
usize = KMEM_STKINFO_LOG_SIZE * sizeof (kmem_stkinfo_t);
log = (kmem_stkinfo_t *)mdb_alloc(usize, UM_SLEEP);
@@ -798,18 +864,15 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
if (log[i].kthread == NULL) {
continue;
}
- mdb_printf("%0?p %0?p %6x %3d%%",
+
+ (void) thread_getdesc((uintptr_t)log[i].kthread,
+ B_TRUE, tdesc, sizeof (tdesc));
+
+ mdb_printf("%0?p %0?p %6x %3d%% %s\n",
log[i].kthread,
log[i].start,
(uint_t)log[i].stksz,
- (int)log[i].percent);
- if (log[i].t_tid != 0) {
- mdb_printf(" %s/%u\n",
- log[i].cmd, log[i].t_tid);
- } else {
- mdb_printf(" %p (%a)\n", log[i].t_startpc,
- log[i].t_startpc);
- }
+ (int)log[i].percent, tdesc);
}
mdb_free((void *)log, usize);
return (DCMD_OK);
@@ -824,7 +887,7 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
}
mdb_printf("%<u>%?s%</u>", "THREAD");
mdb_printf(" %<u>%?s%</u>", "STACK");
- mdb_printf("%<u>%s%</u>", " SIZE CUR MAX CMD/LWPID");
+ mdb_printf("%<u>%s%</u>", " SIZE CUR MAX LWP");
mdb_printf("\n");
}
@@ -838,12 +901,6 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
return (DCMD_OK);
}
- /* read proc */
- if (mdb_vread(&p, sizeof (proc_t), (uintptr_t)t.t_procp) == -1) {
- mdb_warn("failed to read proc at %p\n", t.t_procp);
- return (DCMD_ERR);
- }
-
/*
* Stack grows up or down, see thread_create(),
* compute stack memory aera start and end (start < end).
@@ -878,14 +935,10 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
mdb_printf(" %3d%%", percent);
percent = 0;
+ (void) thread_getdesc(addr, B_TRUE, tdesc, sizeof (tdesc));
+
if (ukmem_stackinfo == 0) {
- mdb_printf(" n/a");
- if (t.t_tid == 0) {
- mdb_printf(" %a()", t.t_startpc);
- } else {
- mdb_printf(" %s/%u", p.p_user.u_comm, t.t_tid);
- }
- mdb_printf("\n");
+ mdb_printf(" n/a %s\n", tdesc);
return (DCMD_OK);
}
@@ -958,12 +1011,9 @@ stackinfo(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
} else {
mdb_printf(" n/a");
}
- if (t.t_tid == 0) {
- mdb_printf(" %a()", t.t_startpc);
- } else {
- mdb_printf(" %s/%u", p.p_user.u_comm, t.t_tid);
- }
- mdb_printf("\n");
+
+ mdb_printf(" %s\n", tdesc);
+
mdb_free((void *)ustack, usize + 8);
return (DCMD_OK);
}
@@ -978,7 +1028,7 @@ stackinfo_help(void)
"(an unsigned integer) is non zero at kthread creation time. ");
mdb_printf("For example:\n");
mdb_printf(
- " THREAD STACK SIZE CUR MAX CMD/LWPID\n");
+ " THREAD STACK SIZE CUR MAX LWP\n");
mdb_printf(
"ffffff014f5f2c20 ffffff0004153000 4f00 4%% 43%% init/1\n");
mdb_printf(
@@ -1002,6 +1052,6 @@ stackinfo_help(void)
"-h shows history, dead kthreads that used their "
"kernel stack the most\n");
mdb_printf(
- "\nSee Solaris Modular Debugger Guide for detailed usage.\n");
+ "\nSee illumos Modular Debugger Guide for detailed usage.\n");
mdb_flush();
}
diff --git a/usr/src/cmd/mdb/common/modules/genunix/thread.h b/usr/src/cmd/mdb/common/modules/genunix/thread.h
index 18952fdc0a..901d962be8 100644
--- a/usr/src/cmd/mdb/common/modules/genunix/thread.h
+++ b/usr/src/cmd/mdb/common/modules/genunix/thread.h
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2018, Joyent, Inc.
*/
#ifndef _THREAD_H
@@ -58,6 +60,8 @@ void thread_state_to_text(uint_t, char *, size_t);
int thread_text_to_state(const char *, uint_t *);
void thread_walk_states(void (*)(uint_t, const char *, void *), void *);
+int thread_getdesc(uintptr_t, boolean_t, char *, size_t);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/nscd/cache.c b/usr/src/cmd/nscd/cache.c
index 2ffb95c30d..288c6e767e 100644
--- a/usr/src/cmd/nscd/cache.c
+++ b/usr/src/cmd/nscd/cache.c
@@ -22,6 +22,7 @@
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Milan Jurik. All rights reserved.
* Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
/*
@@ -1817,8 +1818,10 @@ init_cache_ctx(int i) {
static void
revalidate(nsc_ctx_t *ctx)
{
+ (void) thr_setname(thr_self(), "revalidate");
+
for (;;) {
- int i, slp, interval, count;
+ int i, slp, interval, count;
(void) rw_rdlock(&ctx->cfg_rwlp);
slp = ctx->cfg.pos_ttl;
@@ -1961,6 +1964,8 @@ static void
do_update(nsc_lookup_args_t *in) {
nss_pheader_t *phdr = (nss_pheader_t *)in->buffer;
+ (void) thr_setname(thr_self(), "do_update");
+
/* update the length of the data buffer */
phdr->data_len = phdr->pbufsiz - phdr->data_off;
@@ -2017,7 +2022,7 @@ nsc_invalidate(nsc_ctx_t *ctx, char *dbname, nsc_ctx_t **ctxs)
static void
ctx_invalidate(nsc_ctx_t *ctx)
{
- int i;
+ int i;
nsc_entry_t *entry;
char *me = "ctx_invalidate";
@@ -2190,6 +2195,8 @@ reaper(nsc_ctx_t *ctx)
ulong_t nsc_entries;
char *me = "reaper";
+ (void) thr_setname(thr_self(), me);
+
for (;;) {
(void) mutex_lock(&ctx->stats_mutex);
nsc_entries = ctx->stats.entries;
diff --git a/usr/src/cmd/nscd/nscd_frontend.c b/usr/src/cmd/nscd/nscd_frontend.c
index 7ed5e71bca..134da3f280 100644
--- a/usr/src/cmd/nscd/nscd_frontend.c
+++ b/usr/src/cmd/nscd/nscd_frontend.c
@@ -22,6 +22,7 @@
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
#include <stdlib.h>
@@ -89,6 +90,8 @@ server_tsd_bind(void *arg)
{
static void *value = 0;
+ (void) thr_setname(thr_self(), "server_tsd_bind");
+
/* disable cancellation to avoid hangs if server threads disappear */
(void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
(void) thr_setspecific(server_key, value);
@@ -132,7 +135,8 @@ server_destroy(void *arg)
* get clearance
*/
int
-_nscd_get_clearance(sema_t *sema) {
+_nscd_get_clearance(sema_t *sema)
+{
if (sema_trywait(&common_sema) == 0) {
(void) thr_setspecific(lookup_state_key, NULL);
return (0);
@@ -151,7 +155,8 @@ _nscd_get_clearance(sema_t *sema) {
* release clearance
*/
int
-_nscd_release_clearance(sema_t *sema) {
+_nscd_release_clearance(sema_t *sema)
+{
int which;
(void) thr_getspecific(lookup_state_key, (void**)&which);
@@ -197,7 +202,7 @@ _nscd_restart_if_cfgfile_changed()
static timestruc_t last_nsswitch_modified = { 0 };
static timestruc_t last_resolv_modified = { -1, 0 };
static mutex_t restarting_lock = DEFAULTMUTEX;
- static int restarting = 0;
+ static int restarting = 0;
int restart = 0;
time_t now = time(NULL);
char *me = "_nscd_restart_if_cfgfile_changed";
@@ -1477,6 +1482,8 @@ rts_mon(void)
struct ifa_msghdr *ifam = &mbuf.ifam;
char *me = "rts_mon";
+ (void) thr_setname(thr_self(), me);
+
rt_sock = socket(PF_ROUTE, SOCK_RAW, 0);
if (rt_sock < 0) {
_NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_ERROR)
diff --git a/usr/src/cmd/nscd/nscd_getentctx.c b/usr/src/cmd/nscd/nscd_getentctx.c
index 2fed9a5c82..f4e6b89fbc 100644
--- a/usr/src/cmd/nscd/nscd_getentctx.c
+++ b/usr/src/cmd/nscd/nscd_getentctx.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#include <sys/ccompile.h>
@@ -658,6 +660,8 @@ reclaim_getent_ctx(void *arg)
nss_getent_t nssctx = { 0 };
char *me = "reclaim_getent_ctx";
+ (void) thr_setname(thr_self(), me);
+
/*CONSTCOND*/
while (1) {
@@ -744,7 +748,8 @@ reclaim_getent_ctx(void *arg)
}
static nscd_rc_t
-_nscd_init_getent_ctx_monitor() {
+_nscd_init_getent_ctx_monitor()
+{
int errnum;
char *me = "_nscd_init_getent_ctx_monitor";
@@ -763,7 +768,7 @@ _nscd_init_getent_ctx_monitor() {
* start a thread to reclaim unused getent contexts
*/
if (thr_create(NULL, NULL, reclaim_getent_ctx,
- NULL, THR_DETACHED, NULL) != 0) {
+ NULL, THR_DETACHED, NULL) != 0) {
errnum = errno;
_NSCD_LOG(NSCD_LOG_GETENT_CTX, NSCD_LOG_LEVEL_ERROR)
(me, "thr_create: %s\n", strerror(errnum));
diff --git a/usr/src/cmd/nscd/nscd_selfcred.c b/usr/src/cmd/nscd/nscd_selfcred.c
index df4d2a2c5b..b6cdba8c7a 100644
--- a/usr/src/cmd/nscd/nscd_selfcred.c
+++ b/usr/src/cmd/nscd/nscd_selfcred.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Milan Jurik. All rights reserved.
+ * Copyright 2018 Joyent Inc.
*/
#include <stdio.h>
@@ -425,6 +426,8 @@ forker_monitor(
char *fmri;
char *me = "forker_monitor";
+ (void) thr_setname(thr_self(), me);
+
/* wait until forker exits */
fpid = forker_pid;
(void) selfcred_pulse(forking_door);
@@ -1416,7 +1419,7 @@ check_uid(char *pid_name)
static uid_t uid = 0;
static uid_t euid = 0;
int pfd; /* file descriptor for /proc/<pid>/psinfo */
- psinfo_t info; /* process information from /proc */
+ psinfo_t info; /* process information from /proc */
if (uid == 0) {
pid = getpid();
@@ -1466,6 +1469,8 @@ check_user_process(void *arg)
int found;
char *me = "check_user_process";
+ (void) thr_setname(thr_self(), me);
+
for (;;) {
(void) sleep(60);
diff --git a/usr/src/cmd/nscd/nscd_smfmonitor.c b/usr/src/cmd/nscd/nscd_smfmonitor.c
index bd2ff958ba..c5d5731ecd 100644
--- a/usr/src/cmd/nscd/nscd_smfmonitor.c
+++ b/usr/src/cmd/nscd/nscd_smfmonitor.c
@@ -21,6 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#include <stdlib.h>
@@ -107,6 +109,8 @@ set_smf_state(void *arg)
int i;
int st;
+ (void) thr_setname(thr_self(), "set_smf_state");
+
/*
* the forker nscd needs not monitor the state
* of the client services
diff --git a/usr/src/cmd/prstat/Makefile.com b/usr/src/cmd/prstat/Makefile.com
index e317483142..96c1450b26 100644
--- a/usr/src/cmd/prstat/Makefile.com
+++ b/usr/src/cmd/prstat/Makefile.com
@@ -21,6 +21,7 @@
#
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
+# Copyright 2018, Joyent, Inc.
#
# cmd/prstat/Makefile.com
#
@@ -31,6 +32,7 @@ SRCS = $(OBJS:%.o=../%.c)
include ../../Makefile.cmd
+CSTD = $(CSTD_GNU99)
CFLAGS += $(CCVERBOSE)
CERRWARN += -_gcc=-Wno-parentheses
LDLIBS += -lcurses -lproject
diff --git a/usr/src/cmd/prstat/prstat.c b/usr/src/cmd/prstat/prstat.c
index fc16e435f6..0ff4f51bcd 100644
--- a/usr/src/cmd/prstat/prstat.c
+++ b/usr/src/cmd/prstat/prstat.c
@@ -26,6 +26,7 @@
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018 Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -86,13 +87,13 @@
#define PSINFO_HEADER_PROC_LGRP \
" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/NLWP "
#define PSINFO_HEADER_LWP \
-" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWPID "
+" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/LWP "
#define PSINFO_HEADER_LWP_LGRP \
-" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWPID "
+" PID USERNAME SIZE RSS STATE PRI NICE TIME CPU LGRP PROCESS/LWP "
#define USAGE_HEADER_PROC \
" PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/NLWP "
#define USAGE_HEADER_LWP \
-" PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWPID "
+" PID USERNAME USR SYS TRP TFL DFL LCK SLP LAT VCX ICX SCL SIG PROCESS/LWP "
#define USER_HEADER_PROC \
" NPROC USERNAME SWAP RSS MEMORY TIME CPU "
#define USER_HEADER_LWP \
@@ -110,12 +111,12 @@
#define ZONE_HEADER_LWP \
"ZONEID NLWP SWAP RSS MEMORY TIME CPU ZONE "
#define PSINFO_LINE \
-"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %-.16s/%d"
+"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %s"
#define PSINFO_LINE_LGRP \
-"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %-.16s/%d"
+"%6d %-8s %5s %5s %-6s %3s %3s %9s %3.3s%% %4d %s"
#define USAGE_LINE \
"%6d %-8s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s %3.3s "\
-"%3.3s %3.3s %-.12s/%d"
+"%3.3s %3.3s %s"
#define USER_LINE \
"%6d %-8s %5.5s %5.5s %3.3s%% %9s %3.3s%%"
#define TASK_LINE \
@@ -149,8 +150,8 @@ static table_t prj_tbl = {0, 0, NULL}; /* selected projects */
static table_t tsk_tbl = {0, 0, NULL}; /* selected tasks */
static table_t lgr_tbl = {0, 0, NULL}; /* selected lgroups */
static zonetbl_t zone_tbl = {0, 0, NULL}; /* selected zones */
-static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */
-static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */
+static uidtbl_t euid_tbl = {0, 0, NULL}; /* selected effective users */
+static uidtbl_t ruid_tbl = {0, 0, NULL}; /* selected real users */
static uint_t total_procs; /* total number of procs */
static uint_t total_lwps; /* total number of lwps */
@@ -172,7 +173,7 @@ static long pagesize;
/* default settings */
-static optdesc_t opts = {
+optdesc_t opts = {
5, /* interval between updates, seconds */
15, /* number of lines in top part */
5, /* number of lines in bottom part */
@@ -361,11 +362,12 @@ list_print(list_t *list)
char psize[6], prssize[6], pmem[6], pcpu[6], ptime[12];
char pstate[7], pnice[4], ppri[4];
char pname[LOGNAME_MAX+1];
+ char name[PRFNSZ + THREAD_NAME_MAX + 2];
char projname[PROJNAME_MAX+1];
char zonename[ZONENAME_MAX+1];
float cpu, mem;
double loadavg[3] = {0, 0, 0};
- int i, lwpid;
+ int i, n;
if (list->l_size == 0)
return;
@@ -385,54 +387,59 @@ list_print(list_t *list)
(void) putchar('\r');
(void) putp(t_ulon);
+ n = opts.o_cols;
switch (list->l_type) {
case LT_PROJECTS:
if (opts.o_outpmode & OPT_LWPS)
- (void) printf(PROJECT_HEADER_LWP);
+ n = printf(PROJECT_HEADER_LWP);
else
- (void) printf(PROJECT_HEADER_PROC);
+ n = printf(PROJECT_HEADER_PROC);
break;
case LT_TASKS:
if (opts.o_outpmode & OPT_LWPS)
- (void) printf(TASK_HEADER_LWP);
+ n = printf(TASK_HEADER_LWP);
else
- (void) printf(TASK_HEADER_PROC);
+ n = printf(TASK_HEADER_PROC);
break;
case LT_ZONES:
if (opts.o_outpmode & OPT_LWPS)
- (void) printf(ZONE_HEADER_LWP);
+ n = printf(ZONE_HEADER_LWP);
else
- (void) printf(ZONE_HEADER_PROC);
+ n = printf(ZONE_HEADER_PROC);
break;
case LT_USERS:
if (opts.o_outpmode & OPT_LWPS)
- (void) printf(USER_HEADER_LWP);
+ n = printf(USER_HEADER_LWP);
else
- (void) printf(USER_HEADER_PROC);
+ n = printf(USER_HEADER_PROC);
break;
case LT_LWPS:
if (opts.o_outpmode & OPT_LWPS) {
if (opts.o_outpmode & OPT_PSINFO) {
if (opts.o_outpmode & OPT_LGRP)
- (void) printf(PSINFO_HEADER_LWP_LGRP);
+ n = printf(PSINFO_HEADER_LWP_LGRP);
else
- (void) printf(PSINFO_HEADER_LWP);
+ n = printf(PSINFO_HEADER_LWP);
}
if (opts.o_outpmode & OPT_MSACCT)
- (void) printf(USAGE_HEADER_LWP);
+ n = printf(USAGE_HEADER_LWP);
} else {
if (opts.o_outpmode & OPT_PSINFO) {
if (opts.o_outpmode & OPT_LGRP)
- (void) printf(PSINFO_HEADER_PROC_LGRP);
+ n = printf(PSINFO_HEADER_PROC_LGRP);
else
- (void) printf(PSINFO_HEADER_PROC);
+ n = printf(PSINFO_HEADER_PROC);
}
if (opts.o_outpmode & OPT_MSACCT)
- (void) printf(USAGE_HEADER_PROC);
+ n = printf(USAGE_HEADER_PROC);
}
break;
}
+ /* Pad out the header line so the underline spans the whole width */
+ if ((opts.o_outpmode & OPT_TERMCAP) && n < opts.o_cols)
+ (void) printf("%*s", (int)(opts.o_cols - n), "");
+
(void) putp(t_uloff);
(void) putp(t_eol);
(void) putchar('\n');
@@ -499,15 +506,14 @@ list_print(list_t *list)
break;
case LT_LWPS:
lwp = list->l_ptrs[i];
- if (opts.o_outpmode & OPT_LWPS)
- lwpid = lwp->li_info.pr_lwp.pr_lwpid;
- else
- lwpid = lwp->li_info.pr_nlwp +
- lwp->li_info.pr_nzomb;
+
+ format_name(lwp, name, sizeof (name));
+
pwd_getname(lwp->li_info.pr_uid, pname, sizeof (pname),
opts.o_outpmode & OPT_NORESOLVE,
opts.o_outpmode & (OPT_TERMCAP|OPT_TRUNC),
LOGIN_WIDTH);
+
if (opts.o_outpmode & OPT_PSINFO) {
Format_size(psize, lwp->li_info.pr_size, 6);
Format_size(prssize, lwp->li_info.pr_rssize, 6);
@@ -536,21 +542,17 @@ list_print(list_t *list)
lwp->li_info.pr_time.tv_sec, 10);
if (opts.o_outpmode & OPT_TTY)
(void) putchar('\r');
- stripfname(lwp->li_info.pr_fname);
if (opts.o_outpmode & OPT_LGRP) {
(void) printf(PSINFO_LINE_LGRP,
(int)lwp->li_info.pr_pid, pname,
psize, prssize, pstate,
ppri, pnice, ptime, pcpu,
- (int)lwp->li_info.pr_lwp.pr_lgrp,
- lwp->li_info.pr_fname, lwpid);
+ lwp->li_info.pr_lwp.pr_lgrp, name);
} else {
(void) printf(PSINFO_LINE,
(int)lwp->li_info.pr_pid, pname,
- psize, prssize,
- pstate, ppri, pnice,
- ptime, pcpu,
- lwp->li_info.pr_fname, lwpid);
+ psize, prssize, pstate, ppri, pnice,
+ ptime, pcpu, name);
}
(void) putp(t_eol);
(void) putchar('\n');
@@ -570,12 +572,11 @@ list_print(list_t *list)
Format_pct(lat, lwp->li_lat, 4);
if (opts.o_outpmode & OPT_TTY)
(void) putchar('\r');
- stripfname(lwp->li_info.pr_fname);
(void) printf(USAGE_LINE,
(int)lwp->li_info.pr_pid, pname,
usr, sys, trp, tfl, dfl, lck,
slp, lat, vcx, icx, scl, sig,
- lwp->li_info.pr_fname, lwpid);
+ name);
(void) putp(t_eol);
(void) putchar('\n');
}
@@ -877,6 +878,27 @@ add_proc(psinfo_t *psinfo)
}
static void
+get_lwpname(pid_t pid, id_t lwpid, char *buf, size_t bufsize)
+{
+ char *path = NULL;
+ int fd;
+
+ buf[0] = '\0';
+
+ if (asprintf(&path, "/proc/%d/lwp/%d/lwpname",
+ (int)pid, (int)lwpid) == -1)
+ return;
+
+ if ((fd = open(path, O_RDONLY)) != -1) {
+ (void) read(fd, buf, bufsize);
+ buf[bufsize - 1] = '\0';
+ (void) close(fd);
+ }
+
+ free(path);
+}
+
+static void
add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags)
{
lwp_info_t *lwp;
@@ -891,6 +913,7 @@ add_lwp(psinfo_t *psinfo, lwpsinfo_t *lwpsinfo, int flags)
(void) memcpy(&lwp->li_info, psinfo,
sizeof (psinfo_t) - sizeof (lwpsinfo_t));
(void) memcpy(&lwp->li_info.pr_lwp, lwpsinfo, sizeof (lwpsinfo_t));
+ get_lwpname(pid, lwpid, lwp->li_lwpname, sizeof (lwp->li_lwpname));
}
static void
@@ -1113,7 +1136,7 @@ list_refresh(list_t *list)
}
static void
-curses_on()
+curses_on(void)
{
if ((opts.o_outpmode & OPT_TERMCAP) && (is_curses_on == FALSE)) {
(void) initscr();
@@ -1124,7 +1147,7 @@ curses_on()
}
static void
-curses_off()
+curses_off(void)
{
if ((is_curses_on == TRUE) && (opts.o_outpmode & OPT_TERMCAP)) {
(void) putp(t_rmcup);
@@ -1135,26 +1158,40 @@ curses_off()
}
static int
-nlines()
+nlines(int *linesp, int *colsp)
{
struct winsize ws;
char *envp;
int n;
+
+ *linesp = -1;
+ *colsp = -1;
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) {
if (ws.ws_row > 0)
- return (ws.ws_row);
+ *linesp = ws.ws_row;
+ if (ws.ws_col > 0)
+ *colsp = ws.ws_col;
+ if (ws.ws_row > 0 && ws.ws_col > 0)
+ return (0);
}
- if (envp = getenv("LINES")) {
+
+ if ((envp = getenv("LINES")) != NULL) {
if ((n = Atoi(envp)) > 0) {
opts.o_outpmode &= ~OPT_USEHOME;
- return (n);
+ *linesp = n;
+ }
+ }
+ if ((envp = getenv("COLUMNS")) != NULL) {
+ if ((n = Atoi(envp)) > 0) {
+ *colsp = n;
}
}
- return (-1);
+
+ return ((*linesp > 0 && *colsp > 0) ? 0 : -1);
}
static void
-setmovecur()
+setmovecur(void)
{
int i, n;
if ((opts.o_outpmode & OPT_FULLSCREEN) &&
@@ -1184,17 +1221,19 @@ setmovecur()
}
static int
-setsize()
+setsize(void)
{
static int oldn = 0;
- int n;
+ int cols, n, ret;
if (opts.o_outpmode & OPT_FULLSCREEN) {
- n = nlines();
+ ret = nlines(&n, &cols);
+ if (ret != -1)
+ opts.o_cols = cols;
if (n == oldn)
return (0);
oldn = n;
- if (n == -1) {
+ if (ret == -1) {
opts.o_outpmode &= ~OPT_USEHOME;
setmovecur(); /* set default window size */
return (1);
diff --git a/usr/src/cmd/prstat/prstat.h b/usr/src/cmd/prstat/prstat.h
index 293123c5b9..e205a98bd2 100644
--- a/usr/src/cmd/prstat/prstat.h
+++ b/usr/src/cmd/prstat/prstat.h
@@ -26,6 +26,7 @@
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018 Joyent, Inc. All rights reserved.
*/
#ifndef _PRSTAT_H
@@ -113,6 +114,7 @@ typedef struct lwp_info {
ulong_t li_icx; /* involuntary context switches */
ulong_t li_scl; /* system calls */
ulong_t li_sig; /* received signals */
+ char li_lwpname[THREAD_NAME_MAX];
struct lwp_info *li_next; /* pointer to next lwp */
struct lwp_info *li_prev; /* pointer to previous lwp */
} lwp_info_t;
@@ -167,8 +169,11 @@ typedef struct optdesc {
int o_count; /* number of iterations */
int o_outpmode; /* selected output mode */
int o_sortorder; /* +1 ascending, -1 descending */
+ int o_cols; /* number of columns */
} optdesc_t;
+extern optdesc_t opts;
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/cmd/prstat/prutil.c b/usr/src/cmd/prstat/prutil.c
index 0f9cbd6c4d..551c72cc8a 100644
--- a/usr/src/cmd/prstat/prutil.c
+++ b/usr/src/cmd/prstat/prutil.c
@@ -25,6 +25,7 @@
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018 Joyent, Inc. All rights reserved.
*/
#include <sys/types.h>
@@ -324,14 +325,16 @@ getzonename(zoneid_t zoneid, char *str, size_t len, int trunc, size_t width)
/*
* Remove all unprintable characters from process name
*/
-void
-stripfname(char *buf)
+static void
+stripfname(char *buf, size_t bufsize, const char *pname)
{
int bytesleft = PRFNSZ;
wchar_t wchar;
int length;
char *cp;
+ (void) strlcpy(buf, pname, bufsize);
+
buf[bytesleft - 1] = '\0';
for (cp = buf; *cp != '\0'; cp += length) {
@@ -351,3 +354,71 @@ stripfname(char *buf)
bytesleft -= length;
}
}
+
+
+/*
+ * prstat has always implicitly wanted a terminal width of at least 80 columns
+ * (when a TTY is present). If run in a terminal narrower than 80 columns,
+ * prstat output may wrap. For wider terminals, we allow the last column to use
+ * the additional space.
+ *
+ * We never truncate if using -c, or not outputting to a TTY.
+ */
+static int
+format_namewidth(void)
+{
+ int prefixlen = 0;
+
+ if (opts.o_cols == 0 || !(opts.o_outpmode & (OPT_TERMCAP | OPT_TRUNC)))
+ return (0);
+
+ if (opts.o_outpmode & OPT_PSINFO) {
+ if (opts.o_outpmode & OPT_LGRP)
+ prefixlen = 64;
+ else
+ prefixlen = 59;
+ } else if (opts.o_outpmode & OPT_MSACCT) {
+ prefixlen = 64;
+ }
+
+ return (opts.o_cols - prefixlen);
+}
+
+void
+format_name(lwp_info_t *lwp, char *buf, size_t buflen)
+{
+ int pname_width = PRFNSZ;
+ char nr_suffix[20];
+ char pname[PRFNSZ];
+ int width;
+ int n;
+
+ stripfname(pname, sizeof (pname), lwp->li_info.pr_fname);
+
+ if (opts.o_outpmode & OPT_LWPS) {
+ n = snprintf(nr_suffix, sizeof (nr_suffix), "%d",
+ lwp->li_info.pr_lwp.pr_lwpid);
+ } else {
+ n = snprintf(nr_suffix, sizeof (nr_suffix), "%d",
+ lwp->li_info.pr_nlwp + lwp->li_info.pr_nzomb);
+ }
+
+ width = format_namewidth();
+
+ /* If we're over budget, truncate the process name not the LWP part. */
+ if (strlen(pname) > (width - n - 1)) {
+ pname_width = width - n - 1;
+ pname[pname_width - 1] = '*';
+ }
+
+ if ((opts.o_outpmode & OPT_LWPS) && lwp->li_lwpname[0] != '\0') {
+ n = snprintf(buf, buflen, "%.*s/%s [%s]", pname_width,
+ pname, nr_suffix, lwp->li_lwpname);
+ } else {
+ n = snprintf(buf, buflen, "%.*s/%s", pname_width,
+ pname, nr_suffix);
+ }
+
+ if (width > 0 && strlen(buf) > width)
+ buf[width] = '\0';
+}
diff --git a/usr/src/cmd/prstat/prutil.h b/usr/src/cmd/prstat/prutil.h
index cfa2133714..ae2dbe5a93 100644
--- a/usr/src/cmd/prstat/prutil.h
+++ b/usr/src/cmd/prstat/prutil.h
@@ -25,6 +25,7 @@
* Use is subject to license terms.
*
* Portions Copyright 2009 Chad Mynhier
+ * Copyright 2018, Joyent, Inc.
*/
#ifndef _PRUTIL_H
@@ -54,7 +55,7 @@ extern int Setrlimit();
extern void Priocntl(char *);
extern void getprojname(projid_t, char *, size_t, int, int, size_t);
extern void getzonename(projid_t, char *, size_t, int, size_t);
-extern void stripfname(char *);
+extern void format_name(lwp_info_t *, char *, size_t);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/ps/ps.c b/usr/src/cmd/ps/ps.c
index 78dabbccfe..1a3e91689a 100644
--- a/usr/src/cmd/ps/ps.c
+++ b/usr/src/cmd/ps/ps.c
@@ -27,11 +27,11 @@
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2018, Joyent, Inc.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
-/* All Rights Reserved */
+/* All Rights Reserved */
/*
* ps -- print things about processes.
@@ -108,6 +108,7 @@ enum fname { /* enumeration of field names */
F_SID, /* session id */
F_PSR, /* bound processor */
F_LWP, /* lwp-id */
+ F_LWPNAME, /* lwp name */
F_NLWP, /* number of lwps */
F_OPRI, /* old priority (obsolete) */
F_PRI, /* new priority */
@@ -177,6 +178,7 @@ static struct def_field fname[] = {
{ "sid", "SID", 5, 5 },
{ "psr", "PSR", 3, 2 },
{ "lwp", "LWP", 6, 2 },
+ { "lwpname", "LWPNAME", 32, 8 },
{ "nlwp", "NLWP", 4, 2 },
{ "opri", "PRI", 3, 2 },
{ "pri", "PRI", 3, 2 },
@@ -211,8 +213,8 @@ static struct def_field fname[] = {
{ "zone", "ZONE", 8, 8 },
{ "zoneid", "ZONEID", 5, 5 },
{ "ctid", "CTID", 5, 5 },
- { "lgrp", "LGRP", 4, 2 },
- { "dmodel", "DMODEL", 6, 6 },
+ { "lgrp", "LGRP", 4, 2 },
+ { "dmodel", "DMODEL", 6, 6 },
};
#define NFIELDS (sizeof (fname) / sizeof (fname[0]))
@@ -803,6 +805,7 @@ stdmain(int argc, char **argv)
(void) printf("%-*s",
f->width, f->header);
break;
+ case F_LWPNAME:
case F_FNAME:
case F_COMM:
case F_ARGS:
@@ -1178,7 +1181,8 @@ parse_format(char *arg)
}
for (df = &fname[0]; df < &fname[NFIELDS]; df++)
if (strcmp(name, df->fname) == 0) {
- if (strcmp(name, "lwp") == 0)
+ if (strcmp(name, "lwp") == 0 ||
+ strcmp(name, "lwpname") == 0)
Lflg++;
break;
}
@@ -1754,6 +1758,27 @@ print_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
case F_LWP:
(void) printf("%*d", width, (int)psinfo->pr_lwp.pr_lwpid);
break;
+ case F_LWPNAME: {
+ char lwpname[THREAD_NAME_MAX] = "";
+ char *path = NULL;
+ int fd;
+
+ if (asprintf(&path, "%s/%d/lwp/%d/lwpname", procdir,
+ (int)psinfo->pr_pid, (int)psinfo->pr_lwp.pr_lwpid) != -1 &&
+ (fd = open(path, O_RDONLY)) != -1) {
+ (void) read(fd, lwpname, sizeof (lwpname));
+ lwpname[THREAD_NAME_MAX - 1] = '\0';
+ (void) close(fd);
+ }
+
+ free(path);
+
+ if (f->next != NULL)
+ (void) printf("%-*s", width, lwpname);
+ else
+ (void) printf("%s", lwpname);
+ break;
+ }
case F_NLWP:
(void) printf("%*d", width, psinfo->pr_nlwp + psinfo->pr_nzomb);
break;
@@ -2077,7 +2102,7 @@ print_zombie_field(psinfo_t *psinfo, struct field *f, const char *ttyp)
static void
pr_fields(psinfo_t *psinfo, const char *ttyp,
- void (*print_fld)(psinfo_t *, struct field *, const char *))
+ void (*print_fld)(psinfo_t *, struct field *, const char *))
{
struct field *f;
@@ -2367,7 +2392,7 @@ przom(psinfo_t *psinfo)
}
if (fflg) {
int width = fname[F_STIME].width;
- (void) printf(" %*.*s", width, width, "-"); /* STIME */
+ (void) printf(" %*.*s", width, width, "-"); /* STIME */
}
(void) printf(" %-8.14s", "?"); /* TTY */
@@ -2447,9 +2472,9 @@ delta_secs(const timestruc_t *start)
/*
* Returns the following:
*
- * 0 No error
- * EINVAL Invalid number
- * ERANGE Value exceeds (min, max) range
+ * 0 No error
+ * EINVAL Invalid number
+ * ERANGE Value exceeds (min, max) range
*/
static int
str2id(const char *p, pid_t *val, long min, long max)
@@ -2484,9 +2509,9 @@ str2id(const char *p, pid_t *val, long min, long max)
/*
* Returns the following:
*
- * 0 No error
- * EINVAL Invalid number
- * ERANGE Value exceeds (min, max) range
+ * 0 No error
+ * EINVAL Invalid number
+ * ERANGE Value exceeds (min, max) range
*/
static int
str2uid(const char *p, uid_t *val, unsigned long min, unsigned long max)
diff --git a/usr/src/cmd/ptools/pstack/pstack.c b/usr/src/cmd/ptools/pstack/pstack.c
index 0515ff62d0..d1d55d2280 100644
--- a/usr/src/cmd/ptools/pstack/pstack.c
+++ b/usr/src/cmd/ptools/pstack/pstack.c
@@ -21,6 +21,8 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
#include <sys/isa_defs.h>
@@ -137,7 +139,7 @@ static int thr_stack(const td_thrhandle_t *, void *);
static void free_threadinfo(void);
static struct threadinfo *find_thread(id_t);
static int all_call_stacks(pstack_handle_t *, int);
-static void tlhead(id_t, id_t);
+static void tlhead(id_t, id_t, const char *);
static int print_frame(void *, prgregset_t, uint_t, const long *);
static void print_zombie(struct ps_prochandle *, struct threadinfo *);
static void print_syscall(const lwpstatus_t *, prgregset_t);
@@ -380,6 +382,7 @@ static int
thread_call_stack(void *data, const lwpstatus_t *psp,
const lwpsinfo_t *pip)
{
+ char lwpname[THREAD_NAME_MAX] = "";
pstack_handle_t *h = data;
lwpstatus_t lwpstatus;
struct threadinfo *tip;
@@ -391,7 +394,10 @@ thread_call_stack(void *data, const lwpstatus_t *psp,
if ((tip = find_thread(pip->pr_lwpid)) == NULL)
return (0);
- tlhead(tip->threadid, pip->pr_lwpid);
+ (void) Plwp_getname(h->proc, pip->pr_lwpid,
+ lwpname, sizeof (lwpname));
+
+ tlhead(tip->threadid, pip->pr_lwpid, lwpname);
tip->threadid = 0; /* finish eliminating tid */
if (psp)
call_stack(h, psp);
@@ -410,15 +416,19 @@ thread_call_stack(void *data, const lwpstatus_t *psp,
static int
lwp_call_stack(void *data,
- const lwpstatus_t *psp, const lwpsinfo_t *pip)
+ const lwpstatus_t *psp, const lwpsinfo_t *pip)
{
+ char lwpname[THREAD_NAME_MAX] = "";
pstack_handle_t *h = data;
if (!proc_lwp_in_set(h->lwps, pip->pr_lwpid))
return (0);
h->count++;
- tlhead(0, pip->pr_lwpid);
+ (void) Plwp_getname(h->proc, pip->pr_lwpid,
+ lwpname, sizeof (lwpname));
+
+ tlhead(0, pip->pr_lwpid, lwpname);
if (psp)
call_stack(h, psp);
else
@@ -462,7 +472,7 @@ all_call_stacks(pstack_handle_t *h, int dothreads)
if ((tid = tip->threadid) != 0) {
(void) memcpy(lwpstatus.pr_reg, tip->regs,
sizeof (prgregset_t));
- tlhead(tid, tip->lwpid);
+ tlhead(tid, tip->lwpid, NULL);
if (tip->state == TD_THR_ZOMBIE)
print_zombie(Pr, tip);
else
@@ -475,23 +485,49 @@ all_call_stacks(pstack_handle_t *h, int dothreads)
return (0);
}
+/* The width of the header */
+#define HEAD_WIDTH (62)
static void
-tlhead(id_t threadid, id_t lwpid)
+tlhead(id_t threadid, id_t lwpid, const char *name)
{
+ char buf[128] = { 0 };
+ char num[16];
+ ssize_t amt = 0;
+ int i;
+
if (threadid == 0 && lwpid == 0)
return;
- (void) printf("-----------------");
+ if (lwpid > 0) {
+ (void) snprintf(num, sizeof (num), "%d", (int)lwpid);
+ (void) strlcat(buf, "thread# ", sizeof (buf));
+ (void) strlcat(buf, num, sizeof (buf));
+ }
+
+ if (threadid > 0) {
+ (void) snprintf(num, sizeof (num), "%d", (int)threadid);
+ if (lwpid > 0)
+ (void) strlcat(buf, " / ", sizeof (buf));
+ (void) strlcat(buf, "lwp# ", sizeof (buf));
+ (void) strlcat(buf, num, sizeof (buf));
+ }
+
+ if (name != NULL && strlen(name) > 0) {
+ (void) strlcat(buf, " [", sizeof (buf));
+ (void) strlcat(buf, name, sizeof (buf));
+ (void) strlcat(buf, "]", sizeof (buf));
+ }
- if (threadid && lwpid)
- (void) printf(" lwp# %d / thread# %d ",
- (int)lwpid, (int)threadid);
- else if (threadid)
- (void) printf("--------- thread# %d ", (int)threadid);
- else if (lwpid)
- (void) printf(" lwp# %d ------------", (int)lwpid);
+ amt = (HEAD_WIDTH - strlen(buf) - 2);
+ if (amt < 4)
+ amt = 4;
- (void) printf("--------------------\n");
+ for (i = 0; i < amt / 2; i++)
+ (void) putc('-', stdout);
+ (void) printf(" %s ", buf);
+ for (i = 0; i < (amt / 2) + (amt % 2); i++)
+ (void) putc('-', stdout);
+ (void) putc('\n', stdout);
}
/*ARGSUSED*/
diff --git a/usr/src/cmd/sgs/elfdump/common/corenote.c b/usr/src/cmd/sgs/elfdump/common/corenote.c
index 0777025523..a5ba4e31b8 100644
--- a/usr/src/cmd/sgs/elfdump/common/corenote.c
+++ b/usr/src/cmd/sgs/elfdump/common/corenote.c
@@ -1256,6 +1256,20 @@ dump_prstatus(note_state_t *state, const char *title)
}
+static void
+dump_lwpname(note_state_t *state, const char *title)
+{
+ const sl_prlwpname_layout_t *layout = state->ns_arch->prlwpname;
+
+ indent_enter(state, title, &layout->pr_lwpid);
+
+ PRINT_DEC(MSG_ORIG(MSG_CNOTE_T_PR_LWPID), pr_lwpid);
+ PRINT_STRBUF(MSG_ORIG(MSG_CNOTE_T_PR_LWPNAME), pr_lwpname);
+
+ indent_exit(state);
+}
+
+
/*
* Print percent from 16-bit binary fraction [0 .. 1]
* Round up .01 to .1 to indicate some small percentage (the 0x7000 below).
@@ -1909,6 +1923,11 @@ corenote(Half mach, int do_swap, Word type,
state.ns_v2col = 54;
dump_secflags(&state, MSG_ORIG(MSG_CNOTE_DESC_PRSECFLAGS_T));
return (CORENOTE_R_OK);
+
+ case NT_LWPNAME:
+ state.ns_vcol = 20;
+ dump_lwpname(&state, MSG_ORIG(MSG_CNOTE_DESC_PRLWPNAME_T));
+ return (CORENOTE_R_OK);
}
return (CORENOTE_R_BADTYPE);
diff --git a/usr/src/cmd/sgs/elfdump/common/elfdump.msg b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
index e7488d5373..253ea4a788 100644
--- a/usr/src/cmd/sgs/elfdump/common/elfdump.msg
+++ b/usr/src/cmd/sgs/elfdump/common/elfdump.msg
@@ -22,6 +22,7 @@
#
# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+# Copyright 2018 Joyent, Inc.
#
@ _START_
@@ -469,6 +470,7 @@
@ MSG_CNOTE_DESC_STRUCT_UTSNAME "desc: (struct utsname)"
@ MSG_CNOTE_DESC_PRFDINFO_T "desc: (prfdinfo_t)"
@ MSG_CNOTE_DESC_PRSECFLAGS_T "desc: (prsecflags_t)"
+@ MSG_CNOTE_DESC_PRLWPNAME_T "desc: (prlwpname_t)"
@ MSG_CNOTE_FMT_LINE "%*s%-*s%s"
@ MSG_CNOTE_FMT_LINE_2UP "%*s%-*s%-*s%-*s%s"
@@ -535,6 +537,7 @@
@ MSG_CNOTE_T_PR_LWP "pr_lwp:"
@ MSG_CNOTE_T_PR_LWPHOLD "pr_lwphold:"
@ MSG_CNOTE_T_PR_LWPID "pr_lwpid:"
+@ MSG_CNOTE_T_PR_LWPNAME "pr_lwpname:"
@ MSG_CNOTE_T_PR_LWPPEND "pr_lwppend:"
@ MSG_CNOTE_T_PR_NAME "pr_name:"
@ MSG_CNOTE_T_PR_NGROUPS "pr_ngroups:"
diff --git a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c
index f7af1c1543..674972dc22 100644
--- a/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c
+++ b/usr/src/cmd/sgs/elfdump/common/gen_layout_obj.c
@@ -11,6 +11,7 @@
/*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
/*
@@ -58,3 +59,4 @@ timestruc_t ts;
struct utsname uts;
prfdinfo_t ptfd;
prsecflags_t psf;
+prlwpname_t psn;
diff --git a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c
index d90363c5de..522c974fbd 100644
--- a/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c
+++ b/usr/src/cmd/sgs/elfdump/common/gen_struct_layout.c
@@ -24,11 +24,12 @@
* Use is subject to license terms.
*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
/*
* This program is used to generate the contents of the
- * struct_layout_XXX.c files that contain per-archtecture
+ * struct_layout_XXX.c files that contain per-architecture
* structure layout information.
*
* Although not part of elfdump, it is built by the makefile
@@ -599,6 +600,15 @@ gen_prsecflags(void)
END;
}
+static void
+gen_prlwpname(void)
+{
+ START(prlwpname, prlwpname_t);
+ SCALAR_FIELD(prlwpname_t, pr_lwpid, 0);
+ ARRAY_FIELD(prlwpname_t, pr_lwpname, 0);
+ END;
+}
+
/*ARGSUSED*/
int
main(int argc, char *argv[])
@@ -640,6 +650,7 @@ main(int argc, char *argv[])
gen_utsname();
gen_prfdinfo();
gen_prsecflags();
+ gen_prlwpname();
/*
* Generate the full arch_layout description
@@ -668,6 +679,7 @@ main(int argc, char *argv[])
(void) printf(fmt, "utsname");
(void) printf(fmt, "prfdinfo");
(void) printf(fmt, "prsecflags");
+ (void) printf(fmt, "prlwpname");
(void) printf("};\n");
/*
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout.h b/usr/src/cmd/sgs/elfdump/common/struct_layout.h
index b0592d6909..022640e906 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout.h
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout.h
@@ -26,6 +26,7 @@
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
#ifndef _STRUCT_LAYOUT_H
@@ -98,7 +99,7 @@ typedef struct {
*/
typedef union {
char sld_i8;
- uchar_t sld_ui8;
+ uchar_t sld_ui8;
short sld_i16;
ushort_t sld_ui16;
int32_t sld_i32;
@@ -535,6 +536,12 @@ typedef struct {
sl_field_t pr_upper;
} sl_prsecflags_layout_t;
+typedef struct {
+ sl_field_t sizeof_struct;
+ sl_field_t pr_lwpid;
+ sl_field_t pr_lwpname;
+} sl_prlwpname_layout_t;
+
/*
* This type collects all of the layout definitions for
* a given architecture.
@@ -561,6 +568,7 @@ typedef struct {
const sl_utsname_layout_t *utsname; /* struct utsname */
const sl_prfdinfo_layout_t *prfdinfo; /* prdinfo_t */
const sl_prsecflags_layout_t *prsecflags; /* prsecflags_t */
+ const sl_prlwpname_layout_t *prlwpname; /* prlwpname_t */
} sl_arch_layout_t;
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c
index 2b9469a022..42260b1e43 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_amd64.c
@@ -25,6 +25,7 @@
*/
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
#include <struct_layout.h>
@@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = {
};
+static const sl_prlwpname_layout_t prlwpname_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */
+ { 0, 8, 0, 0 }, /* pr_lwpid */
+ { 8, 1, 32, 0 }, /* pr_lwpname[] */
+};
+
+
static const sl_arch_layout_t layout_amd64 = {
@@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_amd64 = {
&utsname_layout,
&prfdinfo_layout,
&prsecflags_layout,
+ &prlwpname_layout,
};
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c
index 6a516bc225..de104e90ec 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_i386.c
@@ -25,6 +25,7 @@
*/
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
#include <struct_layout.h>
@@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = {
};
+static const sl_prlwpname_layout_t prlwpname_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */
+ { 0, 8, 0, 0 }, /* pr_lwpid */
+ { 8, 1, 32, 0 }, /* pr_lwpname[] */
+};
+
+
static const sl_arch_layout_t layout_i386 = {
@@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_i386 = {
&utsname_layout,
&prfdinfo_layout,
&prsecflags_layout,
+ &prlwpname_layout,
};
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
index 94760c3d82..ead0ae6b7b 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparc.c
@@ -25,7 +25,9 @@
*/
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
+
#include <struct_layout.h>
@@ -386,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = {
};
+static const sl_prlwpname_layout_t prlwpname_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */
+ { 0, 8, 0, 0 }, /* pr_lwpid */
+ { 8, 1, 32, 0 }, /* pr_lwpname[] */
+};
+
+
static const sl_arch_layout_t layout_sparc = {
@@ -410,6 +419,7 @@ static const sl_arch_layout_t layout_sparc = {
&utsname_layout,
&prfdinfo_layout,
&prsecflags_layout,
+ &prlwpname_layout,
};
diff --git a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c
index a194d8136a..00eaae9146 100644
--- a/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c
+++ b/usr/src/cmd/sgs/elfdump/common/struct_layout_sparcv9.c
@@ -25,6 +25,7 @@
*/
/*
* Copyright 2012 DEY Storage Systems, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
#include <struct_layout.h>
@@ -387,6 +388,13 @@ static const sl_prsecflags_layout_t prsecflags_layout = {
};
+static const sl_prlwpname_layout_t prlwpname_layout = {
+ { 0, 40, 0, 0 }, /* sizeof (prlwpname_t) */
+ { 0, 8, 0, 0 }, /* pr_lwpid */
+ { 8, 1, 32, 0 }, /* pr_lwpname[] */
+};
+
+
static const sl_arch_layout_t layout_sparcv9 = {
@@ -411,6 +419,7 @@ static const sl_arch_layout_t layout_sparcv9 = {
&utsname_layout,
&prfdinfo_layout,
&prsecflags_layout,
+ &prlwpname_layout,
};
diff --git a/usr/src/cmd/sgs/libconv/Makefile.com b/usr/src/cmd/sgs/libconv/Makefile.com
index c6287c433c..1bb482f706 100644
--- a/usr/src/cmd/sgs/libconv/Makefile.com
+++ b/usr/src/cmd/sgs/libconv/Makefile.com
@@ -21,7 +21,7 @@
#
# Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2018, Joyent, Inc.
+# Copyright 2018 Joyent, Inc.
#
LIBRARY = libconv.a
@@ -124,8 +124,8 @@ $(LINTOUT64) := LDLIBS += -ldemangle-sys
SGSMSGTARG= $(BLTOBJS:%_msg.o=../common/%.msg)
-LINTFLAGS += -u
-LINTFLAGS64 += -u
+LINTFLAGS += -u -erroff=E_NAME_DECL_NOT_USED_DEF2
+LINTFLAGS64 += -u -erroff=E_NAME_DECL_NOT_USED_DEF2
CLEANFILES += $(BLTDATA) $(LINTOUTS) bld_vernote vernote.s
CLOBBERFILES += $(LINTLIBS)
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c
index 02b3e5d59b..dc9b8022f3 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.c
+++ b/usr/src/cmd/sgs/libconv/common/corenote.c
@@ -58,9 +58,10 @@ conv_cnote_type(Word type, Conv_fmt_flags_t fmt_flags,
MSG_NT_LWPSINFO, MSG_NT_PRPRIV,
MSG_NT_PRPRIVINFO, MSG_NT_CONTENT,
MSG_NT_ZONENAME, MSG_NT_FDINFO,
- MSG_NT_SPYMASTER, MSG_NT_SECFLAGS
+ MSG_NT_SPYMASTER, MSG_NT_SECFLAGS,
+ MSG_NT_LWPNAME,
};
-#if NT_NUM != NT_SECFLAGS
+#if NT_NUM != NT_LWPNAME
#error "NT_NUM has grown. Update core note types[]"
#endif
static const conv_ds_msg_t ds_types = {
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.msg b/usr/src/cmd/sgs/libconv/common/corenote.msg
index b55e67ec07..a36f2bddf7 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.msg
+++ b/usr/src/cmd/sgs/libconv/common/corenote.msg
@@ -49,6 +49,7 @@
@ MSG_NT_FDINFO "[ NT_FDINFO ]"
@ MSG_NT_SPYMASTER "[ NT_SPYMASTER ]"
@ MSG_NT_SECFLAGS "[ NT_SECFLAGS ]"
+@ MSG_NT_LWPNAME "[ NT_LWPNAME ]"
@ MSG_AUXV_AF_SUN_SETUGID "AF_SUN_SETUGID"
diff --git a/usr/src/cmd/svc/startd/graph.c b/usr/src/cmd/svc/startd/graph.c
index 62fbbf1514..0e5253a281 100644
--- a/usr/src/cmd/svc/startd/graph.c
+++ b/usr/src/cmd/svc/startd/graph.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
* Copyright (c) 2015, Syneto S.R.L. All rights reserved.
* Copyright 2016 Toomas Soome <tsoome@me.com>
* Copyright 2016 RackTop Systems.
@@ -576,7 +577,7 @@ typedef enum {
typedef int (*graph_walk_cb_t)(graph_vertex_t *, void *);
typedef struct graph_walk_info {
- graph_walk_dir_t gi_dir;
+ graph_walk_dir_t gi_dir;
uchar_t *gi_visited; /* vertex bitmap */
int (*gi_pre)(graph_vertex_t *, void *);
void (*gi_post)(graph_vertex_t *, void *);
@@ -3849,6 +3850,8 @@ run_sulogin(const char *msg)
static void *
sulogin_thread(void *unused)
{
+ (void) pthread_setname_np(pthread_self(), "sulogin");
+
MUTEX_LOCK(&dgraph_lock);
assert(sulogin_thread_running);
@@ -3876,6 +3879,8 @@ single_user_thread(void *unused)
char *buf;
int r;
+ (void) pthread_setname_np(pthread_self(), "single_user");
+
MUTEX_LOCK(&single_user_thread_lock);
single_user_thread_count++;
@@ -5779,6 +5784,8 @@ graph_event_thread(void *unused)
scf_handle_t *h;
int err;
+ (void) pthread_setname_np(pthread_self(), "graph_event");
+
h = libscf_handle_create_bound_loop();
/*CONSTCOND*/
@@ -6138,6 +6145,8 @@ graph_thread(void *arg)
scf_handle_t *h;
int err;
+ (void) pthread_setname_np(pthread_self(), "graph");
+
h = libscf_handle_create_bound_loop();
if (st->st_initial)
@@ -6794,6 +6803,8 @@ repository_event_thread(void *unused)
char *pg_name = startd_alloc(max_scf_value_size);
int r;
+ (void) pthread_setname_np(pthread_self(), "repository_event");
+
h = libscf_handle_create_bound_loop();
pg = safe_scf_pg_create(h);
diff --git a/usr/src/cmd/svc/startd/method.c b/usr/src/cmd/svc/startd/method.c
index cc9ce6768c..bddae9b027 100644
--- a/usr/src/cmd/svc/startd/method.c
+++ b/usr/src/cmd/svc/startd/method.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Joyent Inc.
+ * Copyright 2018 Joyent, Inc.
*/
/*
@@ -1115,6 +1115,8 @@ method_thread(void *arg)
boolean_t retryable;
restarter_str_t reason;
+ (void) pthread_setname_np(pthread_self(), "method");
+
assert(0 <= info->sf_method_type && info->sf_method_type <= 2);
/* Get (and lock) the restarter_inst_t. */
diff --git a/usr/src/cmd/svc/startd/restarter.c b/usr/src/cmd/svc/startd/restarter.c
index 676cded1c8..a98c863fb5 100644
--- a/usr/src/cmd/svc/startd/restarter.c
+++ b/usr/src/cmd/svc/startd/restarter.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ * Copyright 2018 Joyent, Inc.
*/
/*
@@ -994,6 +994,8 @@ restarter_post_fsminimal_thread(void *unused)
scf_handle_t *h;
int r;
+ (void) pthread_setname_np(pthread_self(), "restarter_post_fsmin");
+
h = libscf_handle_create_bound_loop();
for (;;) {
@@ -1771,6 +1773,8 @@ restarter_process_events(void *arg)
char *fmri = (char *)arg;
struct timespec to;
+ (void) pthread_setname_np(pthread_self(), "restarter_process_events");
+
assert(fmri != NULL);
h = libscf_handle_create_bound_loop();
@@ -1939,8 +1943,8 @@ out:
}
static int
-is_admin_event(restarter_event_type_t t) {
-
+is_admin_event(restarter_event_type_t t)
+{
switch (t) {
case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
@@ -1985,6 +1989,8 @@ restarter_event_thread(void *unused)
{
scf_handle_t *h;
+ (void) pthread_setname_np(pthread_self(), "restarter_event");
+
/*
* This is a new thread, and thus, gets its own handle
* to the repository.
@@ -2196,6 +2202,8 @@ restarter_contracts_event_thread(void *unused)
int fd, err;
scf_handle_t *local_handle;
+ (void) pthread_setname_np(pthread_self(), "restarter_contracts_event");
+
/*
* Await graph load completion. That is, stop here, until we've scanned
* the repository for contract - instance associations.
@@ -2545,6 +2553,8 @@ restarter_timeouts_event_thread(void *unused)
* is not empty.
*/
+ (void) pthread_setname_np(pthread_self(), "restarter_timeouts_event");
+
/*CONSTCOND*/
while (1) {
/*
diff --git a/usr/src/cmd/svc/startd/wait.c b/usr/src/cmd/svc/startd/wait.c
index ebd83be10e..12856ff639 100644
--- a/usr/src/cmd/svc/startd/wait.c
+++ b/usr/src/cmd/svc/startd/wait.c
@@ -21,7 +21,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
- * Copyright 2012, Joyent, Inc. All rights reserved.
+ *
+ * Copyright 2018 Joyent, Inc.
*/
/*
@@ -252,6 +253,8 @@ wait_register(pid_t pid, const char *inst_fmri, int am_parent, int direct)
void *
wait_thread(void *args)
{
+ (void) pthread_setname_np(pthread_self(), "wait");
+
for (;;) {
port_event_t pe;
int fd;