/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <mdb/mdb_target.h>
#include <mdb/mdb_modapi.h>
#include <mdb/mdb_string.h>
#include <libproc.h>
#include <string.h>
/*ARGSUSED*/
void
{
}
int
{
int idc = 0;
const char *p;
void *data;
int argi;
if (flags & DCMD_ADDRSPEC)
/*
* Perform an initial pass through argv: we accumulate integer ids into
* idv, and compute a group of bits to set and a group to clear.
*/
switch (*p++) {
case 'd':
break;
case 'D':
break;
case 'e':
break;
case 's':
break;
case 't':
break;
case 'T':
break;
default:
mdb_warn("illegal option -- "
"+%c\n", p[-1]);
return (DCMD_USAGE);
}
}
} else
return (DCMD_USAGE);
} else
argc--;
argv++;
}
if (idc == 0) {
mdb_warn("expected one or more event IDs to be specified\n");
return (DCMD_USAGE);
}
/*
* If -n was not specified, then -d means "disable now" instead of
* meaning "set auto-disable after n hits".
*/
while (idc-- != 0) {
mdb_warn("cannot modify event %d: internal "
"debugger event\n", id);
continue;
}
if (opt_c[0] != '\0')
else
}
if (opt_n)
}
}
return (status);
}
/*
* Utility routine for performing the stock argument processing that is common
* among the dcmds that create event specifiers. We parse out the standard set
* of event property options from the command-line, and return a copy of the
* argument list to the caller that consists solely of the remaining non-option
* arguments. If a parsing error occurs, NULL is returned.
*/
static const mdb_arg_t *
{
const char *p;
int argi;
int ac = 0;
/* keep lint happy */
/*
* If an address was specified, take it as an additional immediate
* value argument by adding it to the argument list.
*/
if (flags & DCMD_ADDRSPEC) {
}
/*
* Now call mdb_getopts repeatedly to parse the argument list. We need
* to handle '+[a-z]' processing manually, and we also manually copy
* each non-option argument into the av[] array as we encounter them.
*/
#ifdef _KMDB
#endif
switch (*p++) {
case 'd':
break;
case 'D':
break;
case 'e':
break;
case 's':
break;
case 't':
break;
case 'T':
break;
default:
mdb_warn("illegal option -- "
"+%c\n", p[-1]);
return (NULL);
}
}
} else
return (NULL);
} else
argc--;
argv++;
}
/*
* If no arguments were found on the command-line, return NULL to
* indicate that the caller should return DCMD_USAGE.
*/
if (ac == 0)
return (NULL);
/*
* If -n was not specified, then -d means "disable now" instead of
* meaning "set auto-disable after n hits".
*/
/*
* Return the final set of flags, and terminate the argument array
* with a NULL string argument.
*/
return (av);
}
/*
* Utility function for modifying the spec_data and spec_limit properties of an
* event specifier. We use this for handling the -c and -n options below.
*/
static void
{
if (opt_n != 0)
}
}
int
{
int id;
return (DCMD_USAGE);
} else {
}
if (id == 0) {
mdb_warn("failed to add breakpoint at %s",
argv++;
}
return (status);
}
int
{
return (DCMD_USAGE);
mdb_warn("invalid signal name -- %s\n",
argv++;
continue;
}
} else
argv++;
}
return (status);
}
int
{
return (DCMD_USAGE);
mdb_warn("invalid system call name -- %s\n",
argv++;
continue;
}
} else
if (opt_o) {
} else {
}
if (id == 0) {
argv++;
}
return (status);
}
int
{
return (DCMD_USAGE);
mdb_warn("invalid fault name -- %s\n",
argv++;
continue;
}
} else
if (id == 0) {
argv++;
}
return (status);
}
/*ARGSUSED*/
int
{
int id;
int size;
return (DCMD_USAGE);
#ifndef _KMDB
if (opt_i)
return (DCMD_USAGE);
#endif
return (DCMD_USAGE);
if (opt_rwx == 0) {
mdb_warn("at least one of -r, -w, or -x must be specified\n");
return (DCMD_USAGE);
}
mdb_warn("only one of -l, -L, or command count can be "
"specified\n");
return (DCMD_ABORT);
}
if (opt_l) {
return (DCMD_ERR);
}
mdb_warn("cannot set watchpoint: symbol '%s' has zero "
"size\n", buf);
return (DCMD_ERR);
}
} else if (opt_L != 0) {
} else
if (opt_p) {
} else if (opt_i) {
} else {
}
if (id == 0) {
}
/*
* We use m_dcount as an argument; don't loop. We ignore this
* restriction with the -l and -L options, since we read the size from
* the symbol and don't rely on the count.
*/
}
/*ARGSUSED*/
int
{
mdb_warn("failed to add breakpoint");
if (s != NULL)
strfree(s);
return (DCMD_ERR);
}
return (DCMD_OK);
}
/*ARGSUSED*/
static int
{
cmd_event, s) == 0) {
mdb_warn("failed to add watchpoint");
if (s != NULL)
strfree(s);
return (DCMD_ABORT);
}
return (DCMD_ABORT); /* we use m_dcount as an argument; don't loop */
}
int
{
}
int
{
}
int
{
}
static const char _evset_help[] =
"+/-d disable specifier when hit count reaches limit (+d to unset);\n"
" if -n is not present with -d, specifier is disabled immediately\n\n"
"+/-D delete specifier when hit count reaches limit (+D to unset);\n"
"+/-e enable specifier (+e or -d to disable)\n"
"+/-s stop target when hit count reaches limit (+s to unset)\n"
"+/-t delete specifier the next time the target stops (+t to unset)\n"
"+/-T sticky bit: ::delete all will not remove specifier (+T to unset)\n\n"
"-c cmd execute \"cmd\" each time the corresponding event occurs\n"
"-n count set limit for -D, -d, or -s to \"count\" (default 1)\n\n";
void
bp_help(void)
{
mdb_printf("addr set breakpoint at specified virtual address\n");
mdb_printf("sym set deferred breakpoint at specified symbol\n");
}
void
evset_help(void)
{
mdb_printf("addr/id set properties of specified event ids\n");
}
void
fltbp_help(void)
{
mdb_printf("flt fault name (see <sys/fault.h>) or number\n");
}
void
sigbp_help(void)
{
mdb_printf("SIG signal name (see signal(3HEAD)) or number\n");
}
void
sysbp_help(void)
{
mdb_printf("-i trace system call on entry into kernel (default)\n"
"-o trace system call on exit from kernel\n\n"
}
void
wp_help(void)
{
#ifdef _KMDB
"-p treat addr as a physical address\n"
"-i treat addr as an I/O port address\n"
#endif
"-l use size of addr's type for watched region\n"
"-L size set size of watched region (default 1)\n"
"-r trace read access to watched region\n"
"-w trace write access to watched region\n"
"-x trace execute access to watched region\n\n"
"addr address for base of watched region\n"
"repeat size of watched region (equivalent to -L)\n");
}