darwin-xnu/osfmk/ddb/db_cond.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   6 * The contents of this file constitute Original Code as defined in and
   7 * are subject to the Apple Public Source License Version 1.1 (the
   8 * "License").  You may not use this file except in compliance with the
   9 * License.  Please obtain a copy of the License at
  10 * http://www.apple.com/publicsource and read it before using this file.
  11 * 
  12 * This Original Code and all software distributed under the License are
  13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  17 * License for the specific language governing rights and limitations
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22/*
  23 * @OSF_COPYRIGHT@
  24 */
  25/*
  26 * HISTORY
  27 * 
  28 * Revision 1.1.1.1  1998/09/22 21:05:47  wsanchez
  29 * Import of Mac OS X kernel (~semeria)
  30 *
  31 * Revision 1.1.1.1  1998/03/07 02:26:09  wsanchez
  32 * Import of OSF Mach kernel (~mburg)
  33 *
  34 * Revision 1.2.18.1  1997/03/27  18:46:29  barbou
  35 *      ri-osc CR1558: enable use of breakpoint counts even when no
  36 *      condition given.
  37 *      [1995/09/20  15:24:24  bolinger]
  38 *      [97/02/25            barbou]
  39 *
  40 * Revision 1.2.6.2  1996/01/09  19:15:34  devrcs
  41 *      Change 'register c' to 'register int c'.
  42 *      [1995/12/01  21:42:00  jfraser]
  43 * 
  44 *      Merged '64-bit safe' changes from DEC alpha port.
  45 *      [1995/11/21  18:02:54  jfraser]
  46 * 
  47 * Revision 1.2.6.1  1994/09/23  01:18:27  ezf
  48 *      change marker to not FREE
  49 *      [1994/09/22  21:09:37  ezf]
  50 * 
  51 * Revision 1.2.2.4  1993/08/11  20:37:33  elliston
  52 *      Add ANSI Prototypes.  CR #9523.
  53 *      [1993/08/11  03:32:57  elliston]
  54 * 
  55 * Revision 1.2.2.3  1993/07/27  18:26:59  elliston
  56 *      Add ANSI prototypes.  CR #9523.
  57 *      [1993/07/27  18:11:12  elliston]
  58 * 
  59 * Revision 1.2.2.2  1993/06/09  02:19:53  gm
  60 *      Added to OSF/1 R1.3 from NMK15.0.
  61 *      [1993/06/02  20:56:04  jeffc]
  62 * 
  63 * Revision 1.2  1993/04/19  16:01:51  devrcs
  64 *      Changes from mk78:
  65 *      Changed errant call of db_error in db_cond_cmd() to db_printf/db_error.
  66 *      [92/05/20            jfriedl]
  67 *      [93/02/02            bruel]
  68 * 
  69 * Revision 1.1  1992/09/30  02:00:58  robert
  70 *      Initial revision
  71 * 
  72 * $EndLog$
  73 */
  74/* CMU_HIST */
  75/*
  76 * Revision 2.2  91/10/09  15:59:09  af
  77 *       Revision 2.1.3.1  91/10/05  13:05:38  jeffreyh
  78 *              Created to support conditional break point and command execution.
  79 *              [91/08/29            tak]
  80 * 
  81 * Revision 2.1.3.1  91/10/05  13:05:38  jeffreyh
  82 *      Created to support conditional break point and command execution.
  83 *      [91/08/29            tak]
  84 * 
  85 */
  86/* CMU_ENDHIST */
  87/* 
  88 * Mach Operating System
  89 * Copyright (c) 1991,1990 Carnegie Mellon University
  90 * All Rights Reserved.
  91 * 
  92 * Permission to use, copy, modify and distribute this software and its
  93 * documentation is hereby granted, provided that both the copyright
  94 * notice and this permission notice appear in all copies of the
  95 * software, derivative works or modified versions, and any portions
  96 * thereof, and that both notices appear in supporting documentation.
  97 * 
  98 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  99 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 100 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 101 * 
 102 * Carnegie Mellon requests users of this software to return to
 103 * 
 104 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 105 *  School of Computer Science
 106 *  Carnegie Mellon University
 107 *  Pittsburgh PA 15213-3890
 108 * 
 109 * any improvements or extensions that they make and grant Carnegie Mellon
 110 * the rights to redistribute these changes.
 111 */
 112/*
 113 */
 114
 115#include <machine/db_machdep.h>
 116#include <machine/setjmp.h>
 117#include <kern/misc_protos.h>
 118
 119#include <ddb/db_lex.h>
 120#include <ddb/db_break.h>
 121#include <ddb/db_command.h>
 122#include <ddb/db_cond.h>
 123#include <ddb/db_expr.h>
 124#include <ddb/db_output.h>              /* For db_printf() */
 125
 126#define DB_MAX_COND     10              /* maximum conditions to be set */
 127
 128int   db_ncond_free = DB_MAX_COND;                      /* free condition */
 129struct db_cond {
 130        int     c_size;                                 /* size of cond */
 131        char    c_cond_cmd[DB_LEX_LINE_SIZE];           /* cond & cmd */
 132} db_cond[DB_MAX_COND];
 133
 134void
 135db_cond_free(db_thread_breakpoint_t bkpt)
 136{
 137        if (bkpt->tb_cond > 0) {
 138            db_cond[bkpt->tb_cond-1].c_size = 0;
 139            db_ncond_free++;
 140            bkpt->tb_cond = 0;
 141        }
 142}
 143
 144boolean_t
 145db_cond_check(db_thread_breakpoint_t bkpt)
 146{
 147        register  struct db_cond *cp;
 148        db_expr_t value;
 149        int       t;
 150        jmp_buf_t db_jmpbuf;
 151        extern    jmp_buf_t *db_recover;
 152
 153        if (bkpt->tb_cond <= 0) {               /* no condition */
 154                if (--(bkpt->tb_count) > 0)
 155                        return(FALSE);
 156                bkpt->tb_count = bkpt->tb_init_count;
 157            return(TRUE);
 158        }
 159        db_dot = PC_REGS(DDB_REGS);
 160        db_prev = db_dot;
 161        db_next = db_dot;
 162        if (_setjmp(db_recover = &db_jmpbuf)) {
 163            /*
 164             * in case of error, return true to enter interactive mode
 165             */
 166            return(TRUE);
 167        }
 168
 169        /*
 170         * switch input, and evalutate condition
 171         */
 172        cp = &db_cond[bkpt->tb_cond - 1];
 173        db_switch_input(cp->c_cond_cmd, cp->c_size);
 174        if (!db_expression(&value)) {
 175            db_printf("error: condition evaluation error\n");
 176            return(TRUE);
 177        }
 178        if (value == 0 || --(bkpt->tb_count) > 0)
 179            return(FALSE);
 180
 181        /*
 182         * execute a command list if exist
 183         */
 184        bkpt->tb_count = bkpt->tb_init_count;
 185        if ((t = db_read_token()) != tEOL) {
 186            db_unread_token(t);
 187            return(db_exec_cmd_nest(0, 0));
 188        }
 189        return(TRUE);
 190}
 191
 192void
 193db_cond_print(db_thread_breakpoint_t bkpt)
 194{
 195        register char *p, *ep;
 196        register struct db_cond *cp;
 197
 198        if (bkpt->tb_cond <= 0)
 199            return;
 200        cp = &db_cond[bkpt->tb_cond-1];
 201        p = cp->c_cond_cmd;
 202        ep = p + cp->c_size;
 203        while (p < ep) {
 204            if (*p == '\n' || *p == 0)
 205                break;
 206            db_putchar(*p++);
 207        }
 208}
 209
 210void
 211db_cond_cmd(void)
 212{
 213        register  int c;
 214        register  struct db_cond *cp;
 215        register  char *p;
 216        db_expr_t value;
 217        db_thread_breakpoint_t bkpt;
 218
 219        if (db_read_token() != tHASH || db_read_token() != tNUMBER) {
 220            db_printf("#<number> expected instead of \"%s\"\n", db_tok_string);
 221            db_error(0);
 222            return;
 223        }
 224        if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) {
 225            db_printf("No such break point #%d\n", db_tok_number);
 226            db_error(0);
 227            return;
 228        }
 229        /*
 230         * if the break point already has a condition, free it first
 231         */
 232        if (bkpt->tb_cond > 0) {
 233            cp = &db_cond[bkpt->tb_cond - 1];
 234            db_cond_free(bkpt);
 235        } else {
 236            if (db_ncond_free <= 0) {
 237                db_error("Too many conditions\n");
 238                return;
 239            }
 240            for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++)
 241                if (cp->c_size == 0)
 242                    break;
 243            if (cp >= &db_cond[DB_MAX_COND])
 244                panic("bad db_cond_free");
 245        }
 246        for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char());
 247        for (p = cp->c_cond_cmd; c >= 0; c = db_read_char())
 248            *p++ = c;
 249        /*
 250         * switch to saved data and call db_expression to check the condition.
 251         * If no condition is supplied, db_expression will return false.
 252         * In this case, clear previous condition of the break point.
 253         * If condition is supplied, set the condition to the permanent area.
 254         * Note: db_expression will not return here, if the condition
 255         *       expression is wrong.
 256         */
 257        db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd);
 258        if (!db_expression(&value)) {
 259            /* since condition is already freed, do nothing */
 260            db_flush_lex();
 261            return;
 262        }
 263        db_flush_lex();
 264        db_ncond_free--;
 265        cp->c_size = p - cp->c_cond_cmd;
 266        bkpt->tb_cond = (cp - db_cond) + 1;
 267}
 268
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.