Author: trociny
Date: Sat Apr 20 08:17:20 2013
New Revision: 249684
URL: http://svnweb.freebsd.org/changeset/base/249684

Log:
  Add procstat_getkstack function to dump kernel stacks of a process.
  
  MFC after:    1 month

Modified:
  head/lib/libprocstat/Symbol.map
  head/lib/libprocstat/libprocstat.3
  head/lib/libprocstat/libprocstat.c
  head/lib/libprocstat/libprocstat.h

Modified: head/lib/libprocstat/Symbol.map
==============================================================================
--- head/lib/libprocstat/Symbol.map     Sat Apr 20 08:15:43 2013        
(r249683)
+++ head/lib/libprocstat/Symbol.map     Sat Apr 20 08:17:20 2013        
(r249684)
@@ -20,12 +20,14 @@ FBSD_1.3 {
        procstat_freeauxv;
        procstat_freeenvv;
        procstat_freegroups;
+       procstat_freekstack;
        procstat_freevmmap;
        procstat_get_shm_info;
        procstat_getargv;
        procstat_getauxv;
        procstat_getenvv;
        procstat_getgroups;
+       procstat_getkstack;
        procstat_getosrel;
        procstat_getpathname;
        procstat_getrlimit;

Modified: head/lib/libprocstat/libprocstat.3
==============================================================================
--- head/lib/libprocstat/libprocstat.3  Sat Apr 20 08:15:43 2013        
(r249683)
+++ head/lib/libprocstat/libprocstat.3  Sat Apr 20 08:17:20 2013        
(r249684)
@@ -37,6 +37,7 @@
 .Nm procstat_getenvv ,
 .Nm procstat_getfiles ,
 .Nm procstat_getgroups ,
+.Nm procstat_getkstack ,
 .Nm procstat_getosrel ,
 .Nm procstat_getpathname ,
 .Nm procstat_getprocs ,
@@ -47,6 +48,7 @@
 .Nm procstat_freeenvv ,
 .Nm procstat_freefiles ,
 .Nm procstat_freegroups ,
+.Nm procstat_freekstack ,
 .Nm procstat_freeprocs ,
 .Nm procstat_freevmmap ,
 .Nm procstat_get_pipe_info ,
@@ -88,6 +90,11 @@
 .Fa "gid_t *groups"
 .Fc
 .Ft void
+.Fo procstat_freekstack
+.Fa "struct procstat *procstat"
+.Fa "struct kinfo_kstack *kkstp"
+.Fc
+.Ft void
 .Fn procstat_freeprocs "struct procstat *procstat" "struct kinfo_proc *p"
 .Ft void
 .Fo procstat_freevmmap
@@ -166,6 +173,12 @@
 .Fa "struct kinfo_proc *kp"
 .Fa "int *osrelp"
 .Fc
+.Ft "struct kinfo_kstack *"
+.Fo procstat_getkstack
+.Fa "struct procstat *procstat"
+.Fa "struct kinfo_proc *kp"
+.Fa "unsigned int *count"
+.Fc
 .Ft "struct kinfo_proc *"
 .Fo procstat_getprocs
 .Fa "struct procstat *procstat"
@@ -378,6 +391,22 @@ The caller is responsible to free the al
 function call.
 .Pp
 The
+.Fn procstat_getkstack
+function gets a pointer to the
+.Vt procstat
+structure initialized with one of the
+.Fn procstat_open_*
+functions, a pointer to
+.Vt kinfo_proc
+structure, and returns kernel stacks of the process as a dynamically allocated
+array of
+.Vt kinfo_kstack
+structures.
+The caller is responsible to free the allocated memory with a subsequent
+.Fn procstat_freekstack
+function call.
+.Pp
+The
 .Fn procstat_getosrel
 function gets a pointer to the
 .Vt procstat

Modified: head/lib/libprocstat/libprocstat.c
==============================================================================
--- head/lib/libprocstat/libprocstat.c  Sat Apr 20 08:15:43 2013        
(r249683)
+++ head/lib/libprocstat/libprocstat.c  Sat Apr 20 08:17:20 2013        
(r249684)
@@ -142,6 +142,8 @@ static int  procstat_get_vnode_info_sysct
 static gid_t   *procstat_getgroups_core(struct procstat_core *core,
     unsigned int *count);
 static gid_t   *procstat_getgroups_sysctl(pid_t pid, unsigned int *count);
+static struct kinfo_kstack     *procstat_getkstack_sysctl(pid_t pid,
+    int *cntp);
 static int     procstat_getpathname_core(struct procstat_core *core,
     char *pathname, size_t maxlen);
 static int     procstat_getpathname_sysctl(pid_t pid, char *pathname,
@@ -1764,6 +1766,7 @@ struct kinfo_vmentry *
 procstat_getvmmap(struct procstat *procstat, struct kinfo_proc *kp,
     unsigned int *cntp)
 {
+
        switch(procstat->type) {
        case PROCSTAT_KVM:
                warnx("kvm method is not supported");
@@ -2227,3 +2230,70 @@ procstat_freeauxv(struct procstat *procs
 
        free(auxv);
 }
+
+static struct kinfo_kstack *
+procstat_getkstack_sysctl(pid_t pid, int *cntp)
+{
+       struct kinfo_kstack *kkstp;
+       int error, name[4];
+       size_t len;
+
+       name[0] = CTL_KERN;
+       name[1] = KERN_PROC;
+       name[2] = KERN_PROC_KSTACK;
+       name[3] = pid;
+
+       len = 0;
+       error = sysctl(name, 4, NULL, &len, NULL, 0);
+       if (error < 0 && errno != ESRCH && errno != EPERM && errno != ENOENT) {
+               warn("sysctl: kern.proc.kstack: %d", pid);
+               return (NULL);
+       }
+       if (error == -1 && errno == ENOENT) {
+               warnx("sysctl: kern.proc.kstack unavailable"
+                   " (options DDB or options STACK required in kernel)");
+               return (NULL);
+       }
+       if (error == -1)
+               return (NULL);
+       kkstp = malloc(len);
+       if (kkstp == NULL) {
+               warn("malloc(%zu)", len);
+               return (NULL);
+       }
+       if (sysctl(name, 4, kkstp, &len, NULL, 0) == -1) {
+               warn("sysctl: kern.proc.pid: %d", pid);
+               free(kkstp);
+               return (NULL);
+       }
+       *cntp = len / sizeof(*kkstp);
+
+       return (kkstp);
+}
+
+struct kinfo_kstack *
+procstat_getkstack(struct procstat *procstat, struct kinfo_proc *kp,
+    unsigned int *cntp)
+{
+       switch(procstat->type) {
+       case PROCSTAT_KVM:
+               warnx("kvm method is not supported");
+               return (NULL);
+       case PROCSTAT_SYSCTL:
+               return (procstat_getkstack_sysctl(kp->ki_pid, cntp));
+       case PROCSTAT_CORE:
+               warnx("core method is not supported");
+               return (NULL);
+       default:
+               warnx("unknown access method: %d", procstat->type);
+               return (NULL);
+       }
+}
+
+void
+procstat_freekstack(struct procstat *procstat __unused,
+    struct kinfo_kstack *kkstp)
+{
+
+       free(kkstp);
+}

Modified: head/lib/libprocstat/libprocstat.h
==============================================================================
--- head/lib/libprocstat/libprocstat.h  Sat Apr 20 08:15:43 2013        
(r249683)
+++ head/lib/libprocstat/libprocstat.h  Sat Apr 20 08:17:20 2013        
(r249684)
@@ -97,6 +97,7 @@
 #define        PS_FST_FFLAG_EXEC       0x2000
 #define        PS_FST_FFLAG_HASLOCK    0x4000
 
+struct kinfo_kstack;
 struct kinfo_vmentry;
 struct procstat;
 struct rlimit;
@@ -161,6 +162,8 @@ void        procstat_freeauxv(struct procstat *
 #endif
 void   procstat_freeenvv(struct procstat *procstat);
 void   procstat_freegroups(struct procstat *procstat, gid_t *groups);
+void   procstat_freekstack(struct procstat *procstat,
+    struct kinfo_kstack *kkstp);
 void   procstat_freeprocs(struct procstat *procstat, struct kinfo_proc *p);
 void   procstat_freefiles(struct procstat *procstat,
     struct filestat_list *head);
@@ -190,6 +193,8 @@ char        **procstat_getenvv(struct procstat 
     size_t nchr);
 gid_t  *procstat_getgroups(struct procstat *procstat, struct kinfo_proc *kp,
     unsigned int *count);
+struct kinfo_kstack    *procstat_getkstack(struct procstat *procstat,
+    struct kinfo_proc *kp, unsigned int *count);
 int    procstat_getosrel(struct procstat *procstat, struct kinfo_proc *kp,
     int *osrelp);
 int    procstat_getpathname(struct procstat *procstat, struct kinfo_proc *kp,
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to