Print this page
3946 ::gcore
Reviewed by: Adam Leventhal <ahl@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>


   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.

  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/uio.h>
  32 #include <string.h>
  33 #include <errno.h>
  34 #include <limits.h>
  35 
  36 #include "Pcontrol.h"
  37 #include "P32ton.h"
  38 
  39 /*
  40  * This file implements the routines to read and write per-lwp register
  41  * information from either a live process or core file opened with libproc.
  42  * We build up a few common routines for reading and writing register
  43  * information, and then the public functions are all trivial calls to these.
  44  */
  45 
  46 /*
  47  * Utility function to return a pointer to the structure of cached information
  48  * about an lwp in the core file, given its lwpid.
  49  */
  50 static lwp_info_t *
  51 getlwpcore(struct ps_prochandle *P, lwpid_t lwpid)
  52 {
  53         lwp_info_t *lwp = list_next(&P->core->core_lwp_head);

  54         uint_t i;
  55 
  56         for (i = 0; i < P->core->core_nlwp; i++, lwp = list_next(lwp)) {
  57                 if (lwp->lwp_id == lwpid)
  58                         return (lwp);
  59         }
  60 
  61         errno = EINVAL;
  62         return (NULL);
  63 }
  64 
  65 /*
  66  * Utility function to open and read the contents of a per-lwp /proc file.
  67  * This function is used to slurp in lwpstatus, xregs, and asrs.
  68  */
  69 static int
  70 getlwpfile(struct ps_prochandle *P, lwpid_t lwpid,
  71     const char *fbase, void *rp, size_t n)
  72 {
  73         char fname[PATH_MAX];
  74         int fd;
  75 
  76         (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s",


 101          * matches that of the representative lwp:
 102          */
 103         if (P->status.pr_lwp.pr_lwpid == lwpid) {
 104                 (void) memcpy(lps, &P->status.pr_lwp, sizeof (lwpstatus_t));
 105                 return (0);
 106         }
 107 
 108         /*
 109          * If this is a live process, then just read the information out
 110          * of the per-lwp status file:
 111          */
 112         if (P->state != PS_DEAD) {
 113                 return (getlwpfile(P, lwpid, "lwpstatus",
 114                     lps, sizeof (lwpstatus_t)));
 115         }
 116 
 117         /*
 118          * If this is a core file, we need to iterate through our list of
 119          * cached lwp information and then copy out the status.
 120          */
 121         if (P->core != NULL && (lwp = getlwpcore(P, lwpid)) != NULL) {
 122                 (void) memcpy(lps, &lwp->lwp_status, sizeof (lwpstatus_t));
 123                 return (0);
 124         }
 125 
 126         return (-1);
 127 }
 128 
 129 /*
 130  * Utility function to modify lwp registers.  This is done using either the
 131  * process control file or per-lwp control file as necessary.
 132  */
 133 static int
 134 setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd,
 135     const void *rp, size_t n)
 136 {
 137         iovec_t iov[2];
 138         char fname[PATH_MAX];
 139         int fd;
 140 
 141         if (P->state != PS_STOP) {




   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  * Copyright (c) 2013, Joyent, Inc. All rights reserved.
  28  * Copyright (c) 2013 by Delphix. All rights reserved.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/uio.h>
  33 #include <string.h>
  34 #include <errno.h>
  35 #include <limits.h>
  36 
  37 #include "Pcontrol.h"
  38 #include "P32ton.h"
  39 
  40 /*
  41  * This file implements the routines to read and write per-lwp register
  42  * information from either a live process or core file opened with libproc.
  43  * We build up a few common routines for reading and writing register
  44  * information, and then the public functions are all trivial calls to these.
  45  */
  46 
  47 /*
  48  * Utility function to return a pointer to the structure of cached information
  49  * about an lwp in the core file, given its lwpid.
  50  */
  51 static lwp_info_t *
  52 getlwpcore(struct ps_prochandle *P, lwpid_t lwpid)
  53 {
  54         core_info_t *core = P->data;
  55         lwp_info_t *lwp = list_next(&core->core_lwp_head);
  56         uint_t i;
  57 
  58         for (i = 0; i < core->core_nlwp; i++, lwp = list_next(lwp)) {
  59                 if (lwp->lwp_id == lwpid)
  60                         return (lwp);
  61         }
  62 
  63         errno = EINVAL;
  64         return (NULL);
  65 }
  66 
  67 /*
  68  * Utility function to open and read the contents of a per-lwp /proc file.
  69  * This function is used to slurp in lwpstatus, xregs, and asrs.
  70  */
  71 static int
  72 getlwpfile(struct ps_prochandle *P, lwpid_t lwpid,
  73     const char *fbase, void *rp, size_t n)
  74 {
  75         char fname[PATH_MAX];
  76         int fd;
  77 
  78         (void) snprintf(fname, sizeof (fname), "%s/%d/lwp/%d/%s",


 103          * matches that of the representative lwp:
 104          */
 105         if (P->status.pr_lwp.pr_lwpid == lwpid) {
 106                 (void) memcpy(lps, &P->status.pr_lwp, sizeof (lwpstatus_t));
 107                 return (0);
 108         }
 109 
 110         /*
 111          * If this is a live process, then just read the information out
 112          * of the per-lwp status file:
 113          */
 114         if (P->state != PS_DEAD) {
 115                 return (getlwpfile(P, lwpid, "lwpstatus",
 116                     lps, sizeof (lwpstatus_t)));
 117         }
 118 
 119         /*
 120          * If this is a core file, we need to iterate through our list of
 121          * cached lwp information and then copy out the status.
 122          */
 123         if (P->data != NULL && (lwp = getlwpcore(P, lwpid)) != NULL) {
 124                 (void) memcpy(lps, &lwp->lwp_status, sizeof (lwpstatus_t));
 125                 return (0);
 126         }
 127 
 128         return (-1);
 129 }
 130 
 131 /*
 132  * Utility function to modify lwp registers.  This is done using either the
 133  * process control file or per-lwp control file as necessary.
 134  */
 135 static int
 136 setlwpregs(struct ps_prochandle *P, lwpid_t lwpid, long cmd,
 137     const void *rp, size_t n)
 138 {
 139         iovec_t iov[2];
 140         char fname[PATH_MAX];
 141         int fd;
 142 
 143         if (P->state != PS_STOP) {