Print this page
9210 remove KMDB branch debugging support
9211 ::crregs could do with cr2/cr3 support
9209 ::ttrace should be able to filter by thread
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.


  24  */
  25 
  26 /*
  27  * MDB Target Layer
  28  *
  29  * The *target* is the program being inspected by the debugger.  The MDB target
  30  * layer provides a set of functions that insulate common debugger code,
  31  * including the MDB Module API, from the implementation details of how the
  32  * debugger accesses information from a given target.  Each target exports a
  33  * standard set of properties, including one or more address  spaces, one or
  34  * more symbol tables, a set of load objects, and a set of threads that can be
  35  * examined using the interfaces in <mdb/mdb_target.h>.  This technique has
  36  * been employed successfully in other debuggers, including [1], primarily
  37  * to improve portability, although the term "target" often refers to the
  38  * encapsulation of architectural or operating system-specific details.  The
  39  * target abstraction is useful for MDB because it allows us to easily extend
  40  * the debugger to examine a variety of different program forms.  Primarily,
  41  * the target functions validate input arguments and then call an appropriate
  42  * function in the target ops vector, defined in <mdb/mdb_target_impl.h>.
  43  * However, this interface layer provides a very high level of flexibility for


 165 #include <strings.h>
 166 #include <stdlib.h>
 167 #include <errno.h>
 168 
 169 /*
 170  * Define convenience macros for referencing the set of vespec flag bits that
 171  * are preserved by the target implementation, and the set of bits that
 172  * determine automatic ve_hits == ve_limit behavior.
 173  */
 174 #define T_IMPL_BITS     \
 175         (MDB_TGT_SPEC_INTERNAL | MDB_TGT_SPEC_SILENT | MDB_TGT_SPEC_MATCHED | \
 176         MDB_TGT_SPEC_DELETED)
 177 
 178 #define T_AUTO_BITS     \
 179         (MDB_TGT_SPEC_AUTOSTOP | MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS)
 180 
 181 /*
 182  * Define convenience macro for referencing target flag pending continue bits.
 183  */
 184 #define T_CONT_BITS     \
 185         (MDB_TGT_F_STEP | MDB_TGT_F_STEP_OUT | MDB_TGT_F_STEP_BRANCH | \
 186         MDB_TGT_F_NEXT | MDB_TGT_F_CONT)
 187 
 188 mdb_tgt_t *
 189 mdb_tgt_create(mdb_tgt_ctor_f *ctor, int flags, int argc, const char *argv[])
 190 {
 191         mdb_module_t *mp;
 192         mdb_tgt_t *t;
 193 
 194         if (flags & ~MDB_TGT_F_ALL) {
 195                 (void) set_errno(EINVAL);
 196                 return (NULL);
 197         }
 198 
 199         t = mdb_zalloc(sizeof (mdb_tgt_t), UM_SLEEP);
 200         mdb_list_append(&mdb.m_tgtlist, t);
 201 
 202         t->t_module = &mdb.m_rmod;
 203         t->t_matched = T_SE_END;
 204         t->t_flags = flags;
 205         t->t_vepos = 1;
 206         t->t_veneg = 1;


1071         /*
1072          * If the target is undead, dead, or lost, we no longer allow continue.
1073          * This effectively forces the user to use ::kill or ::run after death.
1074          */
1075         if (t->t_status.st_state == MDB_TGT_UNDEAD)
1076                 return (set_errno(EMDB_TGTZOMB));
1077         if (t->t_status.st_state == MDB_TGT_DEAD)
1078                 return (set_errno(EMDB_TGTCORE));
1079         if (t->t_status.st_state == MDB_TGT_LOST)
1080                 return (set_errno(EMDB_TGTLOST));
1081 
1082         /*
1083          * If any of single-step, step-over, or step-out is pending, it takes
1084          * precedence over an explicit or pending continue, because these are
1085          * all different specialized forms of continue.
1086          */
1087         if (t->t_flags & MDB_TGT_F_STEP)
1088                 t_cont = t->t_ops->t_step;
1089         else if (t->t_flags & MDB_TGT_F_NEXT)
1090                 t_cont = t->t_ops->t_step;
1091         else if (t->t_flags & MDB_TGT_F_STEP_BRANCH)
1092                 t_cont = t->t_ops->t_cont;
1093         else if (t->t_flags & MDB_TGT_F_STEP_OUT)
1094                 t_cont = t->t_ops->t_cont;
1095 
1096         /*
1097          * To handle step-over, we ask the target to find the address past the
1098          * next control transfer instruction.  If an address is found, we plant
1099          * a temporary breakpoint there and continue; otherwise just step.
1100          */
1101         if ((t->t_flags & MDB_TGT_F_NEXT) && !(t->t_flags & MDB_TGT_F_STEP)) {
1102                 if (t->t_ops->t_next(t, &addr) == -1 || mdb_tgt_add_vbrkpt(t,
1103                     addr, MDB_TGT_SPEC_HIDDEN | MDB_TGT_SPEC_TEMPORARY,
1104                     no_se_f, NULL) == 0) {
1105                         mdb_dprintf(MDB_DBG_TGT, "next falling back to step: "
1106                             "%s\n", mdb_strerror(errno));
1107                 } else
1108                         t_cont = t->t_ops->t_cont;
1109         }
1110 
1111         /*
1112          * To handle step-out, we ask the target to find the return address of
1113          * the current frame, plant a temporary breakpoint there, and continue.
1114          */
1115         if (t->t_flags & MDB_TGT_F_STEP_OUT) {
1116                 if (t->t_ops->t_step_out(t, &addr) == -1)
1117                         return (-1); /* errno is set for us */
1118 
1119                 if (mdb_tgt_add_vbrkpt(t, addr, MDB_TGT_SPEC_HIDDEN |
1120                     MDB_TGT_SPEC_TEMPORARY, no_se_f, NULL) == 0)
1121                         return (-1); /* errno is set for us */
1122         }
1123 
1124         /*
1125          * To handle step-branch, we ask the target to enable it for the coming
1126          * continue.  Step-branch is incompatible with step, so don't enable it
1127          * if we're going to be stepping.
1128          */
1129         if (t->t_flags & MDB_TGT_F_STEP_BRANCH && t_cont == t->t_ops->t_cont) {
1130                 if (t->t_ops->t_step_branch(t) == -1)
1131                         return (-1); /* errno is set for us */
1132         }
1133 
1134         (void) mdb_signal_block(SIGHUP);
1135         (void) mdb_signal_block(SIGTERM);
1136         mdb_intr_disable();
1137 
1138         t->t_flags &= ~T_CONT_BITS;
1139         t->t_flags |= MDB_TGT_F_BUSY;
1140         mdb_tgt_sespec_arm_all(t);
1141 
1142         ASSERT(t->t_matched != NULL);
1143         matched = t->t_matched;
1144         t->t_matched = T_SE_END;
1145 
1146         if (mdb.m_term != NULL)
1147                 IOP_SUSPEND(mdb.m_term);
1148 
1149         /*
1150          * Iterate over the matched sespec list, performing autostop processing
1151          * and clearing the matched bit for each associated vespec.  We then
1152          * invoke each sespec's se_cont callback in order to continue past
1153          * the corresponding event.  If the matched list has more than one


1377         (void) mdb_tgt_sespec_activate_all(t);
1378 
1379         if (mdb.m_term != NULL)
1380                 IOP_CTL(mdb.m_term, MDB_IOC_CTTY, NULL);
1381 
1382         return (0);
1383 }
1384 
1385 int
1386 mdb_tgt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1387 {
1388         return (tgt_request_continue(t, tsp, MDB_TGT_F_STEP, t->t_ops->t_step));
1389 }
1390 
1391 int
1392 mdb_tgt_step_out(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1393 {
1394         t->t_flags |= MDB_TGT_F_STEP_OUT; /* set flag even if tgt not busy */
1395         return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont));
1396 }
1397 
1398 int
1399 mdb_tgt_step_branch(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1400 {
1401         t->t_flags |= MDB_TGT_F_STEP_BRANCH; /* set flag even if tgt not busy */
1402         return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont));
1403 }
1404 
1405 int
1406 mdb_tgt_next(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1407 {
1408         t->t_flags |= MDB_TGT_F_NEXT; /* set flag even if tgt not busy */
1409         return (tgt_request_continue(t, tsp, 0, t->t_ops->t_step));
1410 }
1411 
1412 int
1413 mdb_tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1414 {
1415         return (tgt_request_continue(t, tsp, MDB_TGT_F_CONT, t->t_ops->t_cont));
1416 }
1417 
1418 int
1419 mdb_tgt_signal(mdb_tgt_t *t, int sig)
1420 {
1421         return (t->t_ops->t_signal(t, sig));
1422 }
1423 




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   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 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  *
  25  * Copyright 2018 Joyent, Inc.
  26  */
  27 
  28 /*
  29  * MDB Target Layer
  30  *
  31  * The *target* is the program being inspected by the debugger.  The MDB target
  32  * layer provides a set of functions that insulate common debugger code,
  33  * including the MDB Module API, from the implementation details of how the
  34  * debugger accesses information from a given target.  Each target exports a
  35  * standard set of properties, including one or more address  spaces, one or
  36  * more symbol tables, a set of load objects, and a set of threads that can be
  37  * examined using the interfaces in <mdb/mdb_target.h>.  This technique has
  38  * been employed successfully in other debuggers, including [1], primarily
  39  * to improve portability, although the term "target" often refers to the
  40  * encapsulation of architectural or operating system-specific details.  The
  41  * target abstraction is useful for MDB because it allows us to easily extend
  42  * the debugger to examine a variety of different program forms.  Primarily,
  43  * the target functions validate input arguments and then call an appropriate
  44  * function in the target ops vector, defined in <mdb/mdb_target_impl.h>.
  45  * However, this interface layer provides a very high level of flexibility for


 167 #include <strings.h>
 168 #include <stdlib.h>
 169 #include <errno.h>
 170 
 171 /*
 172  * Define convenience macros for referencing the set of vespec flag bits that
 173  * are preserved by the target implementation, and the set of bits that
 174  * determine automatic ve_hits == ve_limit behavior.
 175  */
 176 #define T_IMPL_BITS     \
 177         (MDB_TGT_SPEC_INTERNAL | MDB_TGT_SPEC_SILENT | MDB_TGT_SPEC_MATCHED | \
 178         MDB_TGT_SPEC_DELETED)
 179 
 180 #define T_AUTO_BITS     \
 181         (MDB_TGT_SPEC_AUTOSTOP | MDB_TGT_SPEC_AUTODEL | MDB_TGT_SPEC_AUTODIS)
 182 
 183 /*
 184  * Define convenience macro for referencing target flag pending continue bits.
 185  */
 186 #define T_CONT_BITS     \
 187         (MDB_TGT_F_STEP | MDB_TGT_F_STEP_OUT | MDB_TGT_F_NEXT | MDB_TGT_F_CONT)

 188 
 189 mdb_tgt_t *
 190 mdb_tgt_create(mdb_tgt_ctor_f *ctor, int flags, int argc, const char *argv[])
 191 {
 192         mdb_module_t *mp;
 193         mdb_tgt_t *t;
 194 
 195         if (flags & ~MDB_TGT_F_ALL) {
 196                 (void) set_errno(EINVAL);
 197                 return (NULL);
 198         }
 199 
 200         t = mdb_zalloc(sizeof (mdb_tgt_t), UM_SLEEP);
 201         mdb_list_append(&mdb.m_tgtlist, t);
 202 
 203         t->t_module = &mdb.m_rmod;
 204         t->t_matched = T_SE_END;
 205         t->t_flags = flags;
 206         t->t_vepos = 1;
 207         t->t_veneg = 1;


1072         /*
1073          * If the target is undead, dead, or lost, we no longer allow continue.
1074          * This effectively forces the user to use ::kill or ::run after death.
1075          */
1076         if (t->t_status.st_state == MDB_TGT_UNDEAD)
1077                 return (set_errno(EMDB_TGTZOMB));
1078         if (t->t_status.st_state == MDB_TGT_DEAD)
1079                 return (set_errno(EMDB_TGTCORE));
1080         if (t->t_status.st_state == MDB_TGT_LOST)
1081                 return (set_errno(EMDB_TGTLOST));
1082 
1083         /*
1084          * If any of single-step, step-over, or step-out is pending, it takes
1085          * precedence over an explicit or pending continue, because these are
1086          * all different specialized forms of continue.
1087          */
1088         if (t->t_flags & MDB_TGT_F_STEP)
1089                 t_cont = t->t_ops->t_step;
1090         else if (t->t_flags & MDB_TGT_F_NEXT)
1091                 t_cont = t->t_ops->t_step;


1092         else if (t->t_flags & MDB_TGT_F_STEP_OUT)
1093                 t_cont = t->t_ops->t_cont;
1094 
1095         /*
1096          * To handle step-over, we ask the target to find the address past the
1097          * next control transfer instruction.  If an address is found, we plant
1098          * a temporary breakpoint there and continue; otherwise just step.
1099          */
1100         if ((t->t_flags & MDB_TGT_F_NEXT) && !(t->t_flags & MDB_TGT_F_STEP)) {
1101                 if (t->t_ops->t_next(t, &addr) == -1 || mdb_tgt_add_vbrkpt(t,
1102                     addr, MDB_TGT_SPEC_HIDDEN | MDB_TGT_SPEC_TEMPORARY,
1103                     no_se_f, NULL) == 0) {
1104                         mdb_dprintf(MDB_DBG_TGT, "next falling back to step: "
1105                             "%s\n", mdb_strerror(errno));
1106                 } else
1107                         t_cont = t->t_ops->t_cont;
1108         }
1109 
1110         /*
1111          * To handle step-out, we ask the target to find the return address of
1112          * the current frame, plant a temporary breakpoint there, and continue.
1113          */
1114         if (t->t_flags & MDB_TGT_F_STEP_OUT) {
1115                 if (t->t_ops->t_step_out(t, &addr) == -1)
1116                         return (-1); /* errno is set for us */
1117 
1118                 if (mdb_tgt_add_vbrkpt(t, addr, MDB_TGT_SPEC_HIDDEN |
1119                     MDB_TGT_SPEC_TEMPORARY, no_se_f, NULL) == 0)
1120                         return (-1); /* errno is set for us */
1121         }
1122 










1123         (void) mdb_signal_block(SIGHUP);
1124         (void) mdb_signal_block(SIGTERM);
1125         mdb_intr_disable();
1126 
1127         t->t_flags &= ~T_CONT_BITS;
1128         t->t_flags |= MDB_TGT_F_BUSY;
1129         mdb_tgt_sespec_arm_all(t);
1130 
1131         ASSERT(t->t_matched != NULL);
1132         matched = t->t_matched;
1133         t->t_matched = T_SE_END;
1134 
1135         if (mdb.m_term != NULL)
1136                 IOP_SUSPEND(mdb.m_term);
1137 
1138         /*
1139          * Iterate over the matched sespec list, performing autostop processing
1140          * and clearing the matched bit for each associated vespec.  We then
1141          * invoke each sespec's se_cont callback in order to continue past
1142          * the corresponding event.  If the matched list has more than one


1366         (void) mdb_tgt_sespec_activate_all(t);
1367 
1368         if (mdb.m_term != NULL)
1369                 IOP_CTL(mdb.m_term, MDB_IOC_CTTY, NULL);
1370 
1371         return (0);
1372 }
1373 
1374 int
1375 mdb_tgt_step(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1376 {
1377         return (tgt_request_continue(t, tsp, MDB_TGT_F_STEP, t->t_ops->t_step));
1378 }
1379 
1380 int
1381 mdb_tgt_step_out(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1382 {
1383         t->t_flags |= MDB_TGT_F_STEP_OUT; /* set flag even if tgt not busy */
1384         return (tgt_request_continue(t, tsp, 0, t->t_ops->t_cont));
1385 }







1386 
1387 int
1388 mdb_tgt_next(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1389 {
1390         t->t_flags |= MDB_TGT_F_NEXT; /* set flag even if tgt not busy */
1391         return (tgt_request_continue(t, tsp, 0, t->t_ops->t_step));
1392 }
1393 
1394 int
1395 mdb_tgt_continue(mdb_tgt_t *t, mdb_tgt_status_t *tsp)
1396 {
1397         return (tgt_request_continue(t, tsp, MDB_TGT_F_CONT, t->t_ops->t_cont));
1398 }
1399 
1400 int
1401 mdb_tgt_signal(mdb_tgt_t *t, int sig)
1402 {
1403         return (t->t_ops->t_signal(t, sig));
1404 }
1405