Tracks process's program name
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 22 Jul 2014 19:09:13 +0000 (12:09 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 22 Jul 2014 19:09:13 +0000 (12:09 -0700)
Useful for debugging with ps.  I don't track arguments yet, so scripts
all show up as busybox.

Also fixes a leak in an error case of sys_fork().

kern/drivers/dev/proc.c
kern/include/env.h
kern/include/process.h
kern/src/process.c
kern/src/syscall.c

index 68fd7ee..f18276f 100644 (file)
@@ -1110,10 +1110,12 @@ regread:
                        return n;
 #endif
                case Qstatus:{
-                               char buf[8 + 1 + 10 + 1 + 6 + 2];       /* 2 is paranoia */
+                               /* the extra 2 is paranoia */
+                               char buf[8 + 1 + PROC_PROGNAME_SZ + 1 + 10 + 1 + 6 + 2];
                                snprintf(buf, sizeof(buf),
-                                                "%8d %-10s %6d", p->pid, procstate2str(p->state),
-                                                p->ppid);
+                                        "%8d %-*s %-10s %6d", p->pid, PROC_PROGNAME_SZ,
+                                        p->progname, procstate2str(p->state),
+                                        p->ppid);
                                kref_put(&p->p_kref);
                                return readstr(off, va, n, buf);
                        }
index 7d38d56..7b1302e 100644 (file)
@@ -26,6 +26,7 @@
 TAILQ_HEAD(vcore_tailq, vcore);
 /* 'struct proc_list' declared in sched.h (not ideal...) */
 
+#define PROC_PROGNAME_SZ 20
 // TODO: clean this up.
 struct proc {
        TAILQ_ENTRY(proc) proc_arsc_link;
@@ -33,7 +34,7 @@ struct proc {
        spinlock_t proc_lock;
        struct user_context scp_ctx;    /* context for an SCP.  TODO: move to vc0 */
        char user[64]; /* user name */
-
+       char progname[PROC_PROGNAME_SZ];
        pid_t pid;
        /* Tempting to add a struct proc *parent, but we'd need to protect the use
         * of that reference from concurrent parent-death (letting init inherit
index 470d02f..f925c52 100644 (file)
@@ -58,6 +58,7 @@ extern spinlock_t pid_hash_lock;
 
 /* Initialization */
 void proc_init(void);
+void proc_set_progname(struct proc *p, char *name);
 
 /* Process management: */
 struct proc *pid_nth(unsigned int n);
index f7c617d..ad462bd 100644 (file)
@@ -256,6 +256,14 @@ void proc_init(void)
        atomic_init(&num_envs, 0);
 }
 
+void proc_set_progname(struct proc *p, char *name)
+{
+       /* might have an issue if a dentry name isn't null terminated, and we'd get
+        * extra junk up to progname_sz. */
+       strncpy(p->progname, name, PROC_PROGNAME_SZ);
+       p->progname[PROC_PROGNAME_SZ - 1] = '\0';
+}
+
 /* Be sure you init'd the vcore lists before calling this. */
 static void proc_init_procinfo(struct proc* p)
 {
@@ -425,6 +433,7 @@ struct proc *proc_create(struct file *prog, char **argv, char **envp)
        error_t r;
        if ((r = proc_alloc(&p, current, 0 /* flags */)) < 0)
                panic("proc_create: %e", r);    /* one of 3 quaint usages of %e */
+       proc_set_progname(p, file_name(prog));
        procinfo_pack_args(p->procinfo, argv, envp);
        assert(load_elf(p, prog) == 0);
        __proc_ready(p);
@@ -451,6 +460,7 @@ static void __proc_free(struct kref *kref)
        assert(kref_refcnt(&p->p_kref) == 0);
        assert(TAILQ_EMPTY(&p->alarmset.list));
 
+       p->progname[0] = 0;
        cclose(p->dot);
        cclose(p->slash);
        p->dot = p->slash = 0; /* catch bugs */
@@ -2207,10 +2217,18 @@ void print_allpids(void)
        {
                struct proc *p = (struct proc*)item;
                assert(p);
-               printk("%8d %-10s %6d\n", p->pid, procstate2str(p->state), p->ppid);
+               /* this actually adds an extra space, since no progname is ever
+                * PROGNAME_SZ bytes, due to the \0 counted in PROGNAME. */
+               printk("%8d %-*s %-10s %6d\n", p->pid, PROC_PROGNAME_SZ, p->progname,
+                      procstate2str(p->state), p->ppid);
        }
-       printk("     PID STATE      Parent    \n");
-       printk("------------------------------\n");
+       char dashes[PROC_PROGNAME_SZ];
+       memset(dashes, '-', PROC_PROGNAME_SZ);
+       dashes[PROC_PROGNAME_SZ - 1] = '\0';
+       /* -5, for 'Name ' */
+       printk("     PID Name %-*s State      Parent    \n",
+              PROC_PROGNAME_SZ - 5, "");
+       printk("------------------------------%s\n", dashes);
        spin_lock(&pid_hash_lock);
        hash_for_each(pid_hash, print_proc_state);
        spin_unlock(&pid_hash_lock);
@@ -2229,6 +2247,7 @@ void print_proc_info(pid_t pid)
        spinlock_debug(&p->proc_lock);
        //spin_lock(&p->proc_lock); // No locking!!
        printk("struct proc: %p\n", p);
+       printk("Program name: %s\n", p->progname);
        printk("PID: %d\n", p->pid);
        printk("PPID: %d\n", p->ppid);
        printk("State: %s (%p)\n", procstate2str(p->state), p->state);
index f9f999c..a1a1ed6 100644 (file)
@@ -377,6 +377,7 @@ static int sys_proc_create(struct proc *p, char *path, size_t path_l,
                set_errstr("Failed to alloc new proc");
                goto mid_error;
        }
+       proc_set_progname(new_p, file_name(program));
        /* close the CLOEXEC ones, even though this isn't really an exec */
        close_9ns_files(new_p, TRUE);
        close_all_files(&new_p->open_files, TRUE);
@@ -511,12 +512,15 @@ static ssize_t sys_fork(env_t* e)
        ret = proc_alloc(&env, current, PROC_DUP_FGRP);
        assert(!ret);
        assert(env != NULL);
+       proc_set_progname(env, e->progname);
 
        env->heap_top = e->heap_top;
        env->ppid = e->pid;
        disable_irqsave(&state);        /* protect cur_ctx */
        /* Can't really fork if we don't have a current_ctx to fork */
        if (!current_ctx) {
+               proc_destroy(env);
+               proc_decref(env);
                set_errno(EINVAL);
                return -1;
        }
@@ -637,6 +641,7 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
                                   sizeof(pi->argbuf)))
                goto mid_error;
        /* This is the point of no return for the process. */
+       proc_set_progname(p, file_name(program));
        #ifdef CONFIG_X86
        /* clear this, so the new program knows to get an LDT */
        p->procdata->ldt = 0;