db_command.c revision 92756
18876Srgrimes/* 24Srgrimes * Mach Operating System 34Srgrimes * Copyright (c) 1991,1990 Carnegie Mellon University 44Srgrimes * All Rights Reserved. 58876Srgrimes * 64Srgrimes * Permission to use, copy, modify and distribute this software and its 74Srgrimes * documentation is hereby granted, provided that both the copyright 84Srgrimes * notice and this permission notice appear in all copies of the 94Srgrimes * software, derivative works or modified versions, and any portions 104Srgrimes * thereof, and that both notices appear in supporting documentation. 118876Srgrimes * 128876Srgrimes * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 134Srgrimes * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 144Srgrimes * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 158876Srgrimes * 164Srgrimes * Carnegie Mellon requests users of this software to return to 178876Srgrimes * 184Srgrimes * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 194Srgrimes * School of Computer Science 204Srgrimes * Carnegie Mellon University 214Srgrimes * Pittsburgh PA 15213-3890 228876Srgrimes * 234Srgrimes * any improvements or extensions that they make and grant Carnegie the 244Srgrimes * rights to redistribute these changes. 254Srgrimes * 2650477Speter * $FreeBSD: head/sys/ddb/db_command.c 92756 2002-03-20 05:14:42Z alfred $ 274Srgrimes */ 28623Srgrimes 294Srgrimes/* 304Srgrimes * Author: David B. Golub, Carnegie Mellon University 314Srgrimes * Date: 7/90 324Srgrimes */ 33623Srgrimes 344Srgrimes/* 354Srgrimes * Command dispatcher. 364Srgrimes */ 372056Swollman#include <sys/param.h> 3842654Sjdp#include <sys/linker_set.h> 3986998Sdd#include <sys/lock.h> 4086998Sdd#include <sys/mutex.h> 4186998Sdd#include <sys/proc.h> 4217848Spst#include <sys/reboot.h> 4386998Sdd#include <sys/signalvar.h> 442056Swollman#include <sys/systm.h> 4549558Sphk#include <sys/cons.h> 4612734Sbde 472056Swollman#include <ddb/ddb.h> 4812473Sbde#include <ddb/db_command.h> 494Srgrimes#include <ddb/db_lex.h> 504Srgrimes#include <ddb/db_output.h> 514Srgrimes 5286109Sarr#include <machine/md_var.h> 5379418Sjulian#include <machine/setjmp.h> 544Srgrimes 554Srgrimes/* 564Srgrimes * Exported global variables 574Srgrimes */ 584Srgrimesboolean_t db_cmd_loop_done; 5918296Sbdedb_addr_t db_dot; 604Srgrimesjmp_buf db_jmpbuf; 614Srgrimesdb_addr_t db_last_addr; 624Srgrimesdb_addr_t db_prev; 634Srgrimesdb_addr_t db_next; 644Srgrimes 6578161SpeterSET_DECLARE(db_cmd_set, struct command); 6678161SpeterSET_DECLARE(db_show_cmd_set, struct command); 6778161Speter 6812515Sphkstatic db_cmdfcn_t db_fncall; 6917848Spststatic db_cmdfcn_t db_gdb; 7086998Sddstatic db_cmdfcn_t db_kill; 7185944Speterstatic db_cmdfcn_t db_reset; 7217848Spst 7318296Sbde/* XXX this is actually forward-static. */ 7418296Sbdeextern struct command db_show_cmds[]; 7518296Sbde 764Srgrimes/* 774Srgrimes * if 'ed' style: 'dot' is set at start of last item printed, 784Srgrimes * and '+' points to next line. 794Srgrimes * Otherwise: 'dot' points to next item, '..' points to last. 804Srgrimes */ 8112515Sphkstatic boolean_t db_ed_style = TRUE; 824Srgrimes 834Srgrimes/* 844Srgrimes * Utility routine - discard tokens through end-of-line. 854Srgrimes */ 864Srgrimesvoid 874Srgrimesdb_skip_to_eol() 884Srgrimes{ 894Srgrimes int t; 904Srgrimes do { 914Srgrimes t = db_read_token(); 924Srgrimes } while (t != tEOL); 934Srgrimes} 944Srgrimes 954Srgrimes/* 964Srgrimes * Results of command search. 974Srgrimes */ 984Srgrimes#define CMD_UNIQUE 0 994Srgrimes#define CMD_FOUND 1 1004Srgrimes#define CMD_NONE 2 1014Srgrimes#define CMD_AMBIGUOUS 3 1024Srgrimes#define CMD_HELP 4 1034Srgrimes 10492756Salfredstatic void db_cmd_list(struct command *table, 10578161Speter struct command **aux_tablep, 10692756Salfred struct command **aux_tablep_end); 10792756Salfredstatic int db_cmd_search(char *name, struct command *table, 10818296Sbde struct command **aux_tablep, 10978161Speter struct command **aux_tablep_end, 11092756Salfred struct command **cmdp); 11192756Salfredstatic void db_command(struct command **last_cmdp, 11218296Sbde struct command *cmd_table, 11378161Speter struct command **aux_cmd_tablep, 11492756Salfred struct command **aux_cmd_tablep_end); 11512473Sbde 1164Srgrimes/* 1174Srgrimes * Search for command prefix. 1184Srgrimes */ 11912515Sphkstatic int 12078161Speterdb_cmd_search(name, table, aux_tablep, aux_tablep_end, cmdp) 1214Srgrimes char * name; 1224Srgrimes struct command *table; 12318296Sbde struct command **aux_tablep; 12478161Speter struct command **aux_tablep_end; 1254Srgrimes struct command **cmdp; /* out */ 1264Srgrimes{ 1274Srgrimes struct command *cmd; 12818296Sbde struct command **aux_cmdp; 1294Srgrimes int result = CMD_NONE; 1304Srgrimes 1314Srgrimes for (cmd = table; cmd->name != 0; cmd++) { 1324Srgrimes register char *lp; 1334Srgrimes register char *rp; 1344Srgrimes register int c; 1354Srgrimes 1364Srgrimes lp = name; 1374Srgrimes rp = cmd->name; 1384Srgrimes while ((c = *lp) == *rp) { 1394Srgrimes if (c == 0) { 1404Srgrimes /* complete match */ 1414Srgrimes *cmdp = cmd; 1424Srgrimes return (CMD_UNIQUE); 1434Srgrimes } 1444Srgrimes lp++; 1454Srgrimes rp++; 1464Srgrimes } 1474Srgrimes if (c == 0) { 1484Srgrimes /* end of name, not end of command - 1494Srgrimes partial match */ 1504Srgrimes if (result == CMD_FOUND) { 1514Srgrimes result = CMD_AMBIGUOUS; 1524Srgrimes /* but keep looking for a full match - 1534Srgrimes this lets us match single letters */ 1544Srgrimes } 1554Srgrimes else { 1564Srgrimes *cmdp = cmd; 1574Srgrimes result = CMD_FOUND; 1584Srgrimes } 1594Srgrimes } 1604Srgrimes } 16118296Sbde if (result == CMD_NONE && aux_tablep != 0) 16218296Sbde /* XXX repeat too much code. */ 16378161Speter for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) { 16418296Sbde register char *lp; 16518296Sbde register char *rp; 16618296Sbde register int c; 16718296Sbde 16818296Sbde lp = name; 16918296Sbde rp = (*aux_cmdp)->name; 17018296Sbde while ((c = *lp) == *rp) { 17118296Sbde if (c == 0) { 17218296Sbde /* complete match */ 17318296Sbde *cmdp = *aux_cmdp; 17418296Sbde return (CMD_UNIQUE); 17518296Sbde } 17618296Sbde lp++; 17718296Sbde rp++; 17818296Sbde } 17918296Sbde if (c == 0) { 18018296Sbde /* end of name, not end of command - 18118296Sbde partial match */ 18218296Sbde if (result == CMD_FOUND) { 18318296Sbde result = CMD_AMBIGUOUS; 18418296Sbde /* but keep looking for a full match - 18518296Sbde this lets us match single letters */ 18618296Sbde } 18718296Sbde else { 18818296Sbde *cmdp = *aux_cmdp; 18918296Sbde result = CMD_FOUND; 19018296Sbde } 19118296Sbde } 19218296Sbde } 1934Srgrimes if (result == CMD_NONE) { 1944Srgrimes /* check for 'help' */ 1954Srgrimes if (name[0] == 'h' && name[1] == 'e' 1964Srgrimes && name[2] == 'l' && name[3] == 'p') 1974Srgrimes result = CMD_HELP; 1984Srgrimes } 1994Srgrimes return (result); 2004Srgrimes} 2014Srgrimes 20212515Sphkstatic void 20378161Speterdb_cmd_list(table, aux_tablep, aux_tablep_end) 2044Srgrimes struct command *table; 20518296Sbde struct command **aux_tablep; 20678161Speter struct command **aux_tablep_end; 2074Srgrimes{ 2084Srgrimes register struct command *cmd; 20918296Sbde register struct command **aux_cmdp; 2104Srgrimes 2114Srgrimes for (cmd = table; cmd->name != 0; cmd++) { 2124Srgrimes db_printf("%-12s", cmd->name); 2134Srgrimes db_end_line(); 2144Srgrimes } 21518296Sbde if (aux_tablep == 0) 21618296Sbde return; 21778161Speter for (aux_cmdp = aux_tablep; aux_cmdp < aux_tablep_end; aux_cmdp++) { 21818296Sbde db_printf("%-12s", (*aux_cmdp)->name); 21918296Sbde db_end_line(); 22018296Sbde } 2214Srgrimes} 2224Srgrimes 22312515Sphkstatic void 22478161Speterdb_command(last_cmdp, cmd_table, aux_cmd_tablep, aux_cmd_tablep_end) 2254Srgrimes struct command **last_cmdp; /* IN_OUT */ 2264Srgrimes struct command *cmd_table; 22718296Sbde struct command **aux_cmd_tablep; 22878161Speter struct command **aux_cmd_tablep_end; 2294Srgrimes{ 2304Srgrimes struct command *cmd; 2314Srgrimes int t; 2324Srgrimes char modif[TOK_STRING_SIZE]; 2334Srgrimes db_expr_t addr, count; 234798Swollman boolean_t have_addr = FALSE; 2354Srgrimes int result; 2364Srgrimes 2374Srgrimes t = db_read_token(); 2384Srgrimes if (t == tEOL) { 2394Srgrimes /* empty line repeats last command, at 'next' */ 2404Srgrimes cmd = *last_cmdp; 2414Srgrimes addr = (db_expr_t)db_next; 2424Srgrimes have_addr = FALSE; 2434Srgrimes count = 1; 2444Srgrimes modif[0] = '\0'; 2454Srgrimes } 2464Srgrimes else if (t == tEXCL) { 24710348Sbde db_fncall((db_expr_t)0, (boolean_t)0, (db_expr_t)0, (char *)0); 2484Srgrimes return; 2494Srgrimes } 2504Srgrimes else if (t != tIDENT) { 2514Srgrimes db_printf("?\n"); 2524Srgrimes db_flush_lex(); 2534Srgrimes return; 2544Srgrimes } 2554Srgrimes else { 2564Srgrimes /* 2574Srgrimes * Search for command 2584Srgrimes */ 2594Srgrimes while (cmd_table) { 2604Srgrimes result = db_cmd_search(db_tok_string, 2614Srgrimes cmd_table, 26218296Sbde aux_cmd_tablep, 26378161Speter aux_cmd_tablep_end, 2644Srgrimes &cmd); 2654Srgrimes switch (result) { 2664Srgrimes case CMD_NONE: 2674Srgrimes db_printf("No such command\n"); 2684Srgrimes db_flush_lex(); 2694Srgrimes return; 2704Srgrimes case CMD_AMBIGUOUS: 2714Srgrimes db_printf("Ambiguous\n"); 2724Srgrimes db_flush_lex(); 2734Srgrimes return; 2744Srgrimes case CMD_HELP: 27578161Speter db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end); 2764Srgrimes db_flush_lex(); 2774Srgrimes return; 2784Srgrimes default: 2794Srgrimes break; 2804Srgrimes } 2814Srgrimes if ((cmd_table = cmd->more) != 0) { 28218296Sbde /* XXX usually no more aux's. */ 28318296Sbde aux_cmd_tablep = 0; 28418296Sbde if (cmd_table == db_show_cmds) 28578161Speter aux_cmd_tablep = SET_BEGIN(db_show_cmd_set); 28678161Speter aux_cmd_tablep_end = SET_LIMIT(db_show_cmd_set); 28718296Sbde 2884Srgrimes t = db_read_token(); 2894Srgrimes if (t != tIDENT) { 29078161Speter db_cmd_list(cmd_table, aux_cmd_tablep, aux_cmd_tablep_end); 2914Srgrimes db_flush_lex(); 2924Srgrimes return; 2934Srgrimes } 2944Srgrimes } 2954Srgrimes } 2964Srgrimes 2974Srgrimes if ((cmd->flag & CS_OWN) == 0) { 2984Srgrimes /* 2994Srgrimes * Standard syntax: 3004Srgrimes * command [/modifier] [addr] [,count] 3014Srgrimes */ 3024Srgrimes t = db_read_token(); 3034Srgrimes if (t == tSLASH) { 3044Srgrimes t = db_read_token(); 3054Srgrimes if (t != tIDENT) { 3064Srgrimes db_printf("Bad modifier\n"); 3074Srgrimes db_flush_lex(); 3084Srgrimes return; 3094Srgrimes } 3104Srgrimes db_strcpy(modif, db_tok_string); 3114Srgrimes } 3124Srgrimes else { 3134Srgrimes db_unread_token(t); 3144Srgrimes modif[0] = '\0'; 3154Srgrimes } 3164Srgrimes 3174Srgrimes if (db_expression(&addr)) { 3184Srgrimes db_dot = (db_addr_t) addr; 3194Srgrimes db_last_addr = db_dot; 3204Srgrimes have_addr = TRUE; 3214Srgrimes } 3224Srgrimes else { 3234Srgrimes addr = (db_expr_t) db_dot; 3244Srgrimes have_addr = FALSE; 3254Srgrimes } 3264Srgrimes t = db_read_token(); 3274Srgrimes if (t == tCOMMA) { 3284Srgrimes if (!db_expression(&count)) { 3294Srgrimes db_printf("Count missing\n"); 3304Srgrimes db_flush_lex(); 3314Srgrimes return; 3324Srgrimes } 3334Srgrimes } 3344Srgrimes else { 3354Srgrimes db_unread_token(t); 3364Srgrimes count = -1; 3374Srgrimes } 3384Srgrimes if ((cmd->flag & CS_MORE) == 0) { 3394Srgrimes db_skip_to_eol(); 3404Srgrimes } 3414Srgrimes } 3424Srgrimes } 3434Srgrimes *last_cmdp = cmd; 3444Srgrimes if (cmd != 0) { 3454Srgrimes /* 3464Srgrimes * Execute the command. 3474Srgrimes */ 3484Srgrimes (*cmd->fcn)(addr, have_addr, count, modif); 3494Srgrimes 3504Srgrimes if (cmd->flag & CS_SET_DOT) { 3514Srgrimes /* 3524Srgrimes * If command changes dot, set dot to 3534Srgrimes * previous address displayed (if 'ed' style). 3544Srgrimes */ 3554Srgrimes if (db_ed_style) { 3564Srgrimes db_dot = db_prev; 3574Srgrimes } 3584Srgrimes else { 3594Srgrimes db_dot = db_next; 3604Srgrimes } 3614Srgrimes } 3624Srgrimes else { 3634Srgrimes /* 3644Srgrimes * If command does not change dot, 3654Srgrimes * set 'next' location to be the same. 3664Srgrimes */ 3674Srgrimes db_next = db_dot; 3684Srgrimes } 3694Srgrimes } 3704Srgrimes} 3714Srgrimes 3724Srgrimes/* 3734Srgrimes * 'show' commands 3744Srgrimes */ 3752112Swollman 37612515Sphkstatic struct command db_show_all_cmds[] = { 3774Srgrimes#if 0 3781147Sguido { "threads", db_show_all_threads, 0, 0 }, 3792320Sdg#endif 3801549Srgrimes { "procs", db_ps, 0, 0 }, 3814Srgrimes { (char *)0 } 3824Srgrimes}; 3834Srgrimes 38412515Sphkstatic struct command db_show_cmds[] = { 3854Srgrimes { "all", 0, 0, db_show_all_cmds }, 3864Srgrimes { "registers", db_show_regs, 0, 0 }, 3874Srgrimes { "breaks", db_listbreak_cmd, 0, 0 }, 3884Srgrimes#if 0 3894Srgrimes { "thread", db_show_one_thread, 0, 0 }, 3904Srgrimes#endif 3914Srgrimes#if 0 3924Srgrimes { "port", ipc_port_print, 0, 0 }, 3934Srgrimes#endif 3944Srgrimes { (char *)0, } 3954Srgrimes}; 3964Srgrimes 39712515Sphkstatic struct command db_command_table[] = { 3984Srgrimes { "print", db_print_cmd, 0, 0 }, 3996920Sjoerg { "p", db_print_cmd, 0, 0 }, 4004Srgrimes { "examine", db_examine_cmd, CS_SET_DOT, 0 }, 4014Srgrimes { "x", db_examine_cmd, CS_SET_DOT, 0 }, 4024Srgrimes { "search", db_search_cmd, CS_OWN|CS_SET_DOT, 0 }, 4034Srgrimes { "set", db_set_cmd, CS_OWN, 0 }, 4044Srgrimes { "write", db_write_cmd, CS_MORE|CS_SET_DOT, 0 }, 4054Srgrimes { "w", db_write_cmd, CS_MORE|CS_SET_DOT, 0 }, 4064Srgrimes { "delete", db_delete_cmd, 0, 0 }, 4074Srgrimes { "d", db_delete_cmd, 0, 0 }, 4084Srgrimes { "break", db_breakpoint_cmd, 0, 0 }, 4094Srgrimes { "dwatch", db_deletewatch_cmd, 0, 0 }, 4104Srgrimes { "watch", db_watchpoint_cmd, CS_MORE,0 }, 41179573Sbsd { "dhwatch", db_deletehwatch_cmd, 0, 0 }, 41279573Sbsd { "hwatch", db_hwatchpoint_cmd, 0, 0 }, 4134Srgrimes { "step", db_single_step_cmd, 0, 0 }, 4144Srgrimes { "s", db_single_step_cmd, 0, 0 }, 4154Srgrimes { "continue", db_continue_cmd, 0, 0 }, 4164Srgrimes { "c", db_continue_cmd, 0, 0 }, 4174Srgrimes { "until", db_trace_until_call_cmd,0, 0 }, 4184Srgrimes { "next", db_trace_until_matching_cmd,0, 0 }, 4194Srgrimes { "match", db_trace_until_matching_cmd,0, 0 }, 4204Srgrimes { "trace", db_stack_trace_cmd, 0, 0 }, 4214Srgrimes { "call", db_fncall, CS_OWN, 0 }, 4224Srgrimes { "show", 0, 0, db_show_cmds }, 4231147Sguido { "ps", db_ps, 0, 0 }, 42417848Spst { "gdb", db_gdb, 0, 0 }, 42585944Speter { "reset", db_reset, 0, 0 }, 42686998Sdd { "kill", db_kill, CS_OWN, 0 }, 4274Srgrimes { (char *)0, } 4284Srgrimes}; 4294Srgrimes 43012515Sphkstatic struct command *db_last_command = 0; 4314Srgrimes 4327090Sbde#if 0 4334Srgrimesvoid 4344Srgrimesdb_help_cmd() 4354Srgrimes{ 4364Srgrimes struct command *cmd = db_command_table; 4374Srgrimes 4384Srgrimes while (cmd->name != 0) { 4394Srgrimes db_printf("%-12s", cmd->name); 4404Srgrimes db_end_line(); 4414Srgrimes cmd++; 4424Srgrimes } 4434Srgrimes} 4447090Sbde#endif 4454Srgrimes 44633296Sbde/* 44733296Sbde * At least one non-optional command must be implemented using 44833296Sbde * DB_COMMAND() so that db_cmd_set gets created. Here is one. 44933296Sbde */ 45033296SbdeDB_COMMAND(panic, db_panic) 4516204Sphk{ 4527170Sdg panic("from debugger"); 4536204Sphk} 4546204Sphk 4556204Sphkvoid 4564Srgrimesdb_command_loop() 4574Srgrimes{ 4584Srgrimes /* 4594Srgrimes * Initialize 'prev' and 'next' to dot. 4604Srgrimes */ 4614Srgrimes db_prev = db_dot; 4624Srgrimes db_next = db_dot; 4634Srgrimes 4644Srgrimes db_cmd_loop_done = 0; 4654Srgrimes while (!db_cmd_loop_done) { 4664Srgrimes 4674Srgrimes (void) setjmp(db_jmpbuf); 4684Srgrimes if (db_print_position() != 0) 4694Srgrimes db_printf("\n"); 4704Srgrimes 4714Srgrimes db_printf("db> "); 4724Srgrimes (void) db_read_line(); 4734Srgrimes 47418296Sbde db_command(&db_last_command, db_command_table, 47578161Speter SET_BEGIN(db_cmd_set), SET_LIMIT(db_cmd_set)); 4764Srgrimes } 4774Srgrimes} 4784Srgrimes 4794Srgrimesvoid 4804Srgrimesdb_error(s) 4814Srgrimes char *s; 4824Srgrimes{ 4834Srgrimes if (s) 48479884Skris db_printf("%s", s); 4854Srgrimes db_flush_lex(); 4864Srgrimes longjmp(db_jmpbuf, 1); 4874Srgrimes} 4884Srgrimes 4894Srgrimes 4904Srgrimes/* 4914Srgrimes * Call random function: 4924Srgrimes * !expr(arg,arg,arg) 4934Srgrimes */ 49412515Sphkstatic void 49510348Sbdedb_fncall(dummy1, dummy2, dummy3, dummy4) 49610348Sbde db_expr_t dummy1; 49710348Sbde boolean_t dummy2; 49810348Sbde db_expr_t dummy3; 49910348Sbde char * dummy4; 5004Srgrimes{ 5014Srgrimes db_expr_t fn_addr; 50212473Sbde#define MAXARGS 11 /* XXX only 10 are passed */ 5034Srgrimes db_expr_t args[MAXARGS]; 5044Srgrimes int nargs = 0; 5054Srgrimes db_expr_t retval; 50692756Salfred typedef db_expr_t fcn_10args_t(db_expr_t, db_expr_t, db_expr_t, 50712473Sbde db_expr_t, db_expr_t, db_expr_t, 50812473Sbde db_expr_t, db_expr_t, db_expr_t, 50992756Salfred db_expr_t); 51012473Sbde fcn_10args_t *func; 5114Srgrimes int t; 5124Srgrimes 5134Srgrimes if (!db_expression(&fn_addr)) { 5144Srgrimes db_printf("Bad function\n"); 5154Srgrimes db_flush_lex(); 5164Srgrimes return; 5174Srgrimes } 51812473Sbde func = (fcn_10args_t *)fn_addr; /* XXX */ 5194Srgrimes 5204Srgrimes t = db_read_token(); 5214Srgrimes if (t == tLPAREN) { 5224Srgrimes if (db_expression(&args[0])) { 5234Srgrimes nargs++; 5244Srgrimes while ((t = db_read_token()) == tCOMMA) { 5254Srgrimes if (nargs == MAXARGS) { 5264Srgrimes db_printf("Too many arguments\n"); 5274Srgrimes db_flush_lex(); 5284Srgrimes return; 5294Srgrimes } 5304Srgrimes if (!db_expression(&args[nargs])) { 5314Srgrimes db_printf("Argument missing\n"); 5324Srgrimes db_flush_lex(); 5334Srgrimes return; 5344Srgrimes } 5354Srgrimes nargs++; 5364Srgrimes } 5374Srgrimes db_unread_token(t); 5384Srgrimes } 5394Srgrimes if (db_read_token() != tRPAREN) { 5404Srgrimes db_printf("?\n"); 5414Srgrimes db_flush_lex(); 5424Srgrimes return; 5434Srgrimes } 5444Srgrimes } 5454Srgrimes db_skip_to_eol(); 5464Srgrimes 5474Srgrimes while (nargs < MAXARGS) { 5484Srgrimes args[nargs++] = 0; 5494Srgrimes } 5504Srgrimes 5514Srgrimes retval = (*func)(args[0], args[1], args[2], args[3], args[4], 5524Srgrimes args[5], args[6], args[7], args[8], args[9] ); 55348407Speter db_printf("%#lr\n", (long)retval); 5544Srgrimes} 55517848Spst 55617848Spst/* Enter GDB remote protocol debugger on the next trap. */ 55717848Spst 55846783Sphkdev_t gdbdev = NODEV; 55946783Sphkcn_getc_t *gdb_getc; 56046783Sphkcn_putc_t *gdb_putc; 56146658Smckusick 56217848Spststatic void 56317848Spstdb_gdb (dummy1, dummy2, dummy3, dummy4) 56417848Spst db_expr_t dummy1; 56517848Spst boolean_t dummy2; 56617848Spst db_expr_t dummy3; 56717848Spst char * dummy4; 56817848Spst{ 56946658Smckusick 57046783Sphk if (gdbdev == NODEV) { 57146658Smckusick db_printf("No gdb port enabled. Set flag 0x80 on desired port\n"); 57246658Smckusick db_printf("in your configuration file (currently sio only).\n"); 57346658Smckusick return; 57446658Smckusick } 57517848Spst boothowto ^= RB_GDB; 57617848Spst 57717848Spst db_printf("Next trap will enter %s\n", 57817848Spst boothowto & RB_GDB ? "GDB remote protocol mode" 57917848Spst : "DDB debugger"); 58017848Spst} 58185944Speter 58285944Speterstatic void 58386998Sdddb_kill(dummy1, dummy2, dummy3, dummy4) 58486998Sdd db_expr_t dummy1; 58586998Sdd boolean_t dummy2; 58686998Sdd db_expr_t dummy3; 58786998Sdd char * dummy4; 58886998Sdd{ 58986998Sdd db_expr_t old_radix, pid, sig; 59086998Sdd struct proc *p; 59186998Sdd 59286998Sdd#define DB_ERROR(f) do { db_printf f; db_flush_lex(); goto out; } while (0) 59386998Sdd 59486998Sdd /* 59586998Sdd * PIDs and signal numbers are typically represented in base 59686998Sdd * 10, so make that the default here. It can, of course, be 59786998Sdd * overridden by specifying a prefix. 59886998Sdd */ 59986998Sdd old_radix = db_radix; 60086998Sdd db_radix = 10; 60186998Sdd /* Retrieve arguments. */ 60286998Sdd if (!db_expression(&sig)) 60386998Sdd DB_ERROR(("Missing signal number\n")); 60486998Sdd if (!db_expression(&pid)) 60586998Sdd DB_ERROR(("Missing process ID\n")); 60686998Sdd db_skip_to_eol(); 60786998Sdd if (sig < 0 || sig > _SIG_MAXSIG) 60886998Sdd DB_ERROR(("Signal number out of range\n")); 60986998Sdd 61086998Sdd /* 61186998Sdd * Find the process in question. allproc_lock is not needed 61286998Sdd * since we're in DDB. 61386998Sdd */ 61486998Sdd /* sx_slock(&allproc_lock); */ 61586998Sdd LIST_FOREACH(p, &allproc, p_list) 61686998Sdd if (p->p_pid == pid) 61786998Sdd break; 61886998Sdd /* sx_sunlock(&allproc_lock); */ 61986998Sdd if (p == NULL) 62089442Smjacob DB_ERROR(("Can't find process with pid %ld\n", (long) pid)); 62186998Sdd 62286998Sdd /* If it's already locked, bail; otherwise, do the deed. */ 62386998Sdd if (PROC_TRYLOCK(p) == 0) 62489442Smjacob DB_ERROR(("Can't lock process with pid %ld\n", (long) pid)); 62586998Sdd else { 62686998Sdd psignal(p, sig); 62786998Sdd PROC_UNLOCK(p); 62886998Sdd } 62986998Sdd 63086998Sddout: 63186998Sdd db_radix = old_radix; 63286998Sdd#undef DB_ERROR 63386998Sdd} 63486998Sdd 63586998Sddstatic void 63685944Speterdb_reset(dummy1, dummy2, dummy3, dummy4) 63785944Speter db_expr_t dummy1; 63885944Speter boolean_t dummy2; 63985944Speter db_expr_t dummy3; 64085944Speter char * dummy4; 64185944Speter{ 64285944Speter 64385944Speter cpu_reset(); 64485944Speter} 645