[BACK]Return to kdump.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / kdump

Diff for /src/usr.bin/kdump/kdump.c between version 1.83 and 1.84

version 1.83, 2013/07/03 23:04:33 version 1.84, 2013/08/22 02:02:33
Line 37 
Line 37 
 #include <sys/malloc.h>  #include <sys/malloc.h>
 #include <sys/namei.h>  #include <sys/namei.h>
 #include <sys/ptrace.h>  #include <sys/ptrace.h>
 #include <sys/resource.h>  
 #include <sys/sem.h>  #include <sys/sem.h>
 #include <sys/shm.h>  #include <sys/shm.h>
 #include <sys/socket.h>  #include <sys/socket.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
 #include <sys/siginfo.h>  #include <sys/siginfo.h>
 #include <sys/un.h>  
 #include <sys/vmmeter.h>  #include <sys/vmmeter.h>
 #include <sys/stat.h>  
 #include <sys/tty.h>  #include <sys/tty.h>
 #include <sys/wait.h>  #include <sys/wait.h>
 #include <netinet/in.h>  
 #include <arpa/inet.h>  
 #define _KERNEL  #define _KERNEL
 #include <sys/errno.h>  #include <errno.h>
 #undef _KERNEL  #undef _KERNEL
 #include <ddb/db_var.h>  #include <ddb/db_var.h>
 #include <machine/cpu.h>  #include <machine/cpu.h>
Line 66 
Line 61 
 #include <stdlib.h>  #include <stdlib.h>
 #include <stdint.h>  #include <stdint.h>
 #include <string.h>  #include <string.h>
 #include <grp.h>  
 #include <pwd.h>  
 #include <unistd.h>  #include <unistd.h>
 #include <vis.h>  #include <vis.h>
   
Line 82 
Line 75 
 struct ktr_header ktr_header;  struct ktr_header ktr_header;
 pid_t pid = -1;  pid_t pid = -1;
   
 #define TIME_FORMAT     "%b %e %T %Y"  
 #define eqs(s1, s2)     (strcmp((s1), (s2)) == 0)  #define eqs(s1, s2)     (strcmp((s1), (s2)) == 0)
   
 #include <sys/syscall.h>  #include <sys/syscall.h>
Line 157 
Line 149 
 static void ktrsyscall(struct ktr_syscall *);  static void ktrsyscall(struct ktr_syscall *);
 static const char *kresolvsysctl(int, int *, int);  static const char *kresolvsysctl(int, int *, int);
 static void ktrsysret(struct ktr_sysret *);  static void ktrsysret(struct ktr_sysret *);
 static void ktrstruct(char *, size_t);  
 static void ktruser(struct ktr_user *, size_t);  static void ktruser(struct ktr_user *, size_t);
 static void setemul(const char *);  static void setemul(const char *);
 static void usage(void);  static void usage(void);
Line 166 
Line 157 
 static void pgid(int);  static void pgid(int);
 static void wait4pid(int);  static void wait4pid(int);
 static void signame(int);  static void signame(int);
 static void sigset(int);  
 static void semctlname(int);  static void semctlname(int);
 static void shmctlname(int);  static void shmctlname(int);
 static void semgetname(int);  static void semgetname(int);
Line 1289 
Line 1279 
 }  }
   
 static void  static void
 ktrsockaddr(struct sockaddr *sa)  
 {  
 /*  
  TODO: Support additional address families  
         #include <netnatm/natm.h>  
         struct sockaddr_natm    *natm;  
         #include <netsmb/netbios.h>  
         struct sockaddr_nb      *nb;  
 */  
         char addr[64];  
   
         /*  
          * note: ktrstruct() has already verified that sa points to a  
          * buffer at least sizeof(struct sockaddr) bytes long and exactly  
          * sa->sa_len bytes long.  
          */  
         printf("struct sockaddr { ");  
         sockfamilyname(sa->sa_family);  
         printf(", ");  
   
 #define check_sockaddr_len(n)                                   \  
         if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \  
                 printf("invalid");                              \  
                 break;                                          \  
         }  
   
         switch(sa->sa_family) {  
         case AF_INET: {  
                 struct sockaddr_in      *sa_in;  
   
                 sa_in = (struct sockaddr_in *)sa;  
                 check_sockaddr_len(in);  
                 inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);  
                 printf("%s:%u", addr, ntohs(sa_in->sin_port));  
                 break;  
         }  
         case AF_INET6: {  
                 struct sockaddr_in6     *sa_in6;  
   
                 sa_in6 = (struct sockaddr_in6 *)sa;  
                 check_sockaddr_len(in6);  
                 inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);  
                 printf("[%s]:%u", addr, htons(sa_in6->sin6_port));  
                 break;  
         }  
 #ifdef IPX  
         case AF_IPX: {  
                 struct sockaddr_ipx     *sa_ipx;  
   
                 sa_ipx = (struct sockaddr_ipx *)sa;  
                 check_sockaddr_len(ipx);  
                 /* XXX wish we had ipx_ntop */  
                 printf("%s", ipx_ntoa(sa_ipx->sipx_addr));  
                 break;  
         }  
 #endif  
         case AF_UNIX: {  
                 struct sockaddr_un *sa_un;  
   
                 sa_un = (struct sockaddr_un *)sa;  
                 if (sa_un->sun_len <= sizeof(sa_un->sun_len) +  
                     sizeof(sa_un->sun_family)) {  
                         printf("invalid");  
                         break;  
                 }  
                 printf("\"%.*s\"", (int)(sa_un->sun_len -  
                     sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),  
                     sa_un->sun_path);  
                 break;  
         }  
         default:  
                 printf("unknown address family");  
         }  
         printf(" }\n");  
 }  
   
 static void  
 print_time(time_t t, int relative)  
 {  
         char timestr[PATH_MAX + 4];  
         struct tm *tm;  
   
         if (resolv == 0 || relative)  
                 printf("%jd", (intmax_t)t);  
         else {  
                 tm = localtime(&t);  
                 (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);  
                 printf("\"%s\"", timestr);  
         }  
 }  
   
 static void  
 print_timespec(const struct timespec *tsp, int relative)  
 {  
         print_time(tsp->tv_sec, relative);  
         if (tsp->tv_nsec != 0)  
                 printf(".%09ld", tsp->tv_nsec);  
 }  
   
 static void  
 ktrstat(const struct stat *statp)  
 {  
         char mode[12];  
         struct passwd *pwd;  
         struct group  *grp;  
   
         /*  
          * note: ktrstruct() has already verified that statp points to a  
          * buffer exactly sizeof(struct stat) bytes long.  
          */  
         printf("struct stat { ");  
         strmode(statp->st_mode, mode);  
         printf("dev=%d, ino=%llu, mode=%s, nlink=%u, ",  
             statp->st_dev, (unsigned long long)statp->st_ino,  
             mode, statp->st_nlink);  
         if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)  
                 printf("uid=%u, ", statp->st_uid);  
         else  
                 printf("uid=\"%s\", ", pwd->pw_name);  
         if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)  
                 printf("gid=%u, ", statp->st_gid);  
         else  
                 printf("gid=\"%s\", ", grp->gr_name);  
         printf("rdev=%d, ", statp->st_rdev);  
         printf("atime=");  
         print_timespec(&statp->st_atim, 0);  
         printf(", mtime=");  
         print_timespec(&statp->st_mtim, 0);  
         printf(", ctime=");  
         print_timespec(&statp->st_ctim, 0);  
         printf(", size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",  
             statp->st_size, statp->st_blocks, statp->st_blksize,  
             statp->st_flags, statp->st_gen);  
         printf(" }\n");  
 }  
   
 static void  
 ktrtimespec(const struct timespec *tsp, int relative)  
 {  
         printf("struct timespec { ");  
         print_timespec(tsp, relative);  
         printf(" }\n");  
 }  
   
 static void  
 ktrtimeval(const struct timeval *tvp, int relative)  
 {  
         printf("struct timeval { ");  
         print_time(tvp->tv_sec, relative);  
         if (tvp->tv_usec != 0)  
                 printf(".%06ld", tvp->tv_usec);  
         printf(" }\n");  
 }  
   
 static void  
 ktrsigaction(const struct sigaction *sa)  
 {  
         /*  
          * note: ktrstruct() has already verified that sa points to a  
          * buffer exactly sizeof(struct sigaction) bytes long.  
          */  
         printf("struct sigaction { ");  
         if (sa->sa_handler == SIG_DFL)  
                 printf("handler=SIG_DFL");  
         else if (sa->sa_handler == SIG_IGN)  
                 printf("handler=SIG_IGN");  
         else if (sa->sa_flags & SA_SIGINFO)  
                 printf("sigaction=%p", (void *)sa->sa_sigaction);  
         else  
                 printf("handler=%p", (void *)sa->sa_handler);  
         printf(", mask=");  
         sigset(sa->sa_mask);  
         printf(", flags=");  
         sigactionflagname(sa->sa_flags);  
         printf(" }\n");  
 }  
   
 static void  
 print_rlim(rlim_t lim)  
 {  
         if (lim == RLIM_INFINITY)  
                 printf("infinite");  
         else  
                 printf("%llu", (unsigned long long)lim);  
 }  
   
 static void  
 ktrrlimit(const struct rlimit *limp)  
 {  
         printf("struct rlimit { ");  
         printf("cur=");  
         print_rlim(limp->rlim_cur);  
         printf(", max=");  
         print_rlim(limp->rlim_max);  
         printf(" }\n");  
 }  
   
 static void  
 ktrtfork(const struct __tfork *tf)  
 {  
         printf("struct __tfork { tcb=%p, tid=%p, stack=%p }\n",  
             tf->tf_tcb, (void *)tf->tf_tid, tf->tf_stack);  
 }  
   
 static void  
 ktrfdset(const struct fd_set *fds, int len)  
 {  
         int nfds, i, start = -1;  
         char sep = ' ';  
   
         nfds = len * NBBY;  
         printf("struct fd_set {");  
         for (i = 0; i <= nfds; i++)  
                 if (i != nfds && FD_ISSET(i, fds)) {  
                         if (start == -1)  
                                 start = i;  
                 } else if (start != -1) {  
                         putchar(sep);  
                         if (start == i - 1)  
                                 printf("%d", start);  
                         else if (start == i - 2)  
                                 printf("%d,%d", start, i - 1);  
                         else  
                                 printf("%d-%d", start, i - 1);  
                         sep = ',';  
                         start = -1;  
                 }  
   
         printf(" }\n");  
 }  
   
 static void  
 ktrstruct(char *buf, size_t buflen)  
 {  
         char *name, *data;  
         size_t namelen, datalen;  
         int i;  
   
         for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';  
              ++namelen)  
                 /* nothing */;  
         if (namelen == buflen)  
                 goto invalid;  
         if (name[namelen] != '\0')  
                 goto invalid;  
         data = buf + namelen + 1;  
         datalen = buflen - namelen - 1;  
         if (datalen == 0)  
                 goto invalid;  
         /* sanity check */  
         for (i = 0; i < namelen; ++i)  
                 if (!isalpha((unsigned char)name[i]))  
                         goto invalid;  
         if (strcmp(name, "stat") == 0) {  
                 struct stat sb;  
   
                 if (datalen != sizeof(struct stat))  
                         goto invalid;  
                 memcpy(&sb, data, datalen);  
                 ktrstat(&sb);  
         } else if (strcmp(name, "sockaddr") == 0) {  
                 struct sockaddr_storage ss;  
   
                 if (datalen > sizeof(ss))  
                         goto invalid;  
                 memcpy(&ss, data, datalen);  
                 if ((ss.ss_family != AF_UNIX &&  
                     datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)  
                         goto invalid;  
                 ktrsockaddr((struct sockaddr *)&ss);  
         } else if (strcmp(name, "abstimespec") == 0 ||  
             strcmp(name, "reltimespec") == 0) {  
                 struct timespec ts;  
   
                 if (datalen != sizeof(ts))  
                         goto invalid;  
                 memcpy(&ts, data, datalen);  
                 ktrtimespec(&ts, name[0] == 'r');  
         } else if (strcmp(name, "abstimeval") == 0 ||  
             strcmp(name, "reltimeval") == 0) {  
                 struct timeval tv;  
   
                 if (datalen != sizeof(tv))  
                         goto invalid;  
                 memcpy(&tv, data, datalen);  
                 ktrtimeval(&tv, name[0] == 'r');  
         } else if (strcmp(name, "sigaction") == 0) {  
                 struct sigaction sa;  
   
                 if (datalen != sizeof(sa))  
                         goto invalid;  
                 memcpy(&sa, data, datalen);  
                 ktrsigaction(&sa);  
         } else if (strcmp(name, "rlimit") == 0) {  
                 struct rlimit lim;  
   
                 if (datalen != sizeof(lim))  
                         goto invalid;  
                 memcpy(&lim, data, datalen);  
                 ktrrlimit(&lim);  
         } else if (strcmp(name, "tfork") == 0) {  
                 struct __tfork tf;  
   
                 if (datalen != sizeof(tf))  
                         goto invalid;  
                 memcpy(&tf, data, datalen);  
                 ktrtfork(&tf);  
         } else if (strcmp(name, "fdset") == 0) {  
                 struct fd_set *fds;  
                 if ((fds = malloc(datalen)) == NULL)  
                         err(1, "malloc");  
                 memcpy(fds, data, datalen);  
                 ktrfdset(fds, datalen);  
                 free(fds);  
         } else {  
                 printf("unknown structure %s\n", name);  
         }  
         return;  
 invalid:  
         printf("invalid record\n");  
 }  
   
 static void  
 ktruser(struct ktr_user *usr, size_t len)  ktruser(struct ktr_user *usr, size_t len)
 {  {
         len -= sizeof(struct ktr_user);          len -= sizeof(struct ktr_user);
Line 1693 
Line 1360 
                 (void)printf("SIG %d", sig);                  (void)printf("SIG %d", sig);
 }  }
   
 static void  void
 sigset(int ss)  sigset(int ss)
 {  {
         int     or = 0;          int     or = 0;

Legend:
Removed from v.1.83  
changed lines
  Added in v.1.84