1 /*- 2 * Copyright (c) 2007 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /*- 28 * Simple DDB scripting mechanism. Each script consists of a named list of 29 * DDB commands to execute sequentially. A more sophisticated scripting 30 * language might be desirable, but would be significantly more complex to 31 * implement. A more interesting syntax might allow general use of variables 32 * and extracting of useful values, such as a thread's process identifier, 33 * for passing into further DDB commands. Certain scripts are run 34 * automatically at kdb_enter(), if defined, based on how the debugger is 35 * entered, allowing scripted responses to panics, break signals, etc. 36 * 37 * Scripts may be managed from within DDB using the script, scripts, and 38 * unscript commands. They may also be managed from userspace using ddb(8), 39 * which operates using a set of sysctls. 40 * 41 * TODO: 42 * - Allow scripts to be defined using tunables so that they can be defined 43 * before boot and be present in single-user mode without boot scripts 44 * running. 45 * - Memory allocation is not possible from within DDB, so we use a set of 46 * statically allocated buffers to hold defined scripts. However, when 47 * scripts are being defined from userspace via sysctl, we could in fact be 48 * using malloc(9) and therefore not impose a static limit, giving greater 49 * flexibility and avoiding hard-defined buffer limits. 50 * - When scripts run automatically on entrance to DDB, placing "continue" at 51 * the end still results in being in the debugger, as we unconditionally 52 * run db_command_loop() after the script. There should be a way to avoid 53 * this. 54 */ 55 56 #include <sys/cdefs.h> 57 __FBSDID("$FreeBSD$"); 58 59 #include <sys/param.h> 60 #include <sys/kdb.h> 61 #include <sys/kernel.h> 62 #include <sys/libkern.h> 63 #include <sys/lock.h> 64 #include <sys/malloc.h> 65 #include <sys/mutex.h> 66 #include <sys/sbuf.h> 67 #include <sys/sysctl.h> 68 #include <sys/systm.h> 69 70 #include <ddb/ddb.h> 71 #include <ddb/db_command.h> 72 #include <ddb/db_lex.h> 73 74 #include <machine/setjmp.h> 75 76 /* 77 * struct ddb_script describes an individual script. 78 */ 79 struct ddb_script { 80 char ds_scriptname[DB_MAXSCRIPTNAME]; 81 char ds_script[DB_MAXSCRIPTLEN]; 82 }; 83 84 /* 85 * Global list of scripts -- defined scripts have non-empty name fields. 86 */ 87 static struct ddb_script db_script_table[DB_MAXSCRIPTS]; 88 89 /* 90 * While executing a script, we parse it using strsep(), so require a 91 * temporary buffer that may be used destructively. Since we support weak 92 * recursion of scripts (one may reference another), we need one buffer for 93 * each concurrently executing script. 94 */ 95 static struct db_recursion_data { 96 char drd_buffer[DB_MAXSCRIPTLEN]; 97 } db_recursion_data[DB_MAXSCRIPTRECURSION]; 98 static int db_recursion = -1; 99 100 /* 101 * We use a separate static buffer for script validation so that it is safe 102 * to validate scripts from within a script. This is used only in 103 * db_script_valid(), which should never be called reentrantly. 104 */ 105 static char db_static_buffer[DB_MAXSCRIPTLEN]; 106 107 /* 108 * Synchronization is not required from within the debugger, as it is 109 * singe-threaded (although reentrance must be carefully considered). 110 * However, it is required when interacting with scripts from user space 111 * processes. Sysctl procedures acquire db_script_mtx before accessing the 112 * global script data structures. 113 */ 114 static struct mtx db_script_mtx; 115 MTX_SYSINIT(db_script_mtx, &db_script_mtx, "db_script_mtx", MTX_DEF); 116 117 /* 118 * Some script names have special meaning, such as those executed 119 * automatically when KDB is entered. 120 */ 121 #define DB_SCRIPT_KDBENTER_PREFIX "kdb.enter" /* KDB has entered. */ 122 #define DB_SCRIPT_KDBENTER_DEFAULT "kdb.enter.default" 123 124 /* 125 * Find the existing script slot for a named script, if any. 126 */ 127 static struct ddb_script * 128 db_script_lookup(const char *scriptname) 129 { 130 int i; 131 132 for (i = 0; i < DB_MAXSCRIPTS; i++) { 133 if (strcmp(db_script_table[i].ds_scriptname, scriptname) == 134 0) 135 return (&db_script_table[i]); 136 } 137 return (NULL); 138 } 139 140 /* 141 * Find a new slot for a script, if available. Does not mark as allocated in 142 * any way--this must be done by the caller. 143 */ 144 static struct ddb_script * 145 db_script_new(void) 146 { 147 int i; 148 149 for (i = 0; i < DB_MAXSCRIPTS; i++) { 150 if (strlen(db_script_table[i].ds_scriptname) == 0) 151 return (&db_script_table[i]); 152 } 153 return (NULL); 154 } 155 156 /* 157 * Perform very rudimentary validation of a proposed script. It would be 158 * easy to imagine something more comprehensive. The script string is 159 * validated in a static buffer. 160 */ 161 static int 162 db_script_valid(const char *scriptname, const char *script) 163 { 164 char *buffer, *command; 165 166 if (strlen(scriptname) == 0) 167 return (EINVAL); 168 if (strlen(scriptname) >= DB_MAXSCRIPTNAME) 169 return (EINVAL); 170 if (strlen(script) >= DB_MAXSCRIPTLEN) 171 return (EINVAL); 172 buffer = db_static_buffer; 173 strcpy(buffer, script); 174 while ((command = strsep(&buffer, ";")) != NULL) { 175 if (strlen(command) >= DB_MAXLINE) 176 return (EINVAL); 177 } 178 return (0); 179 } 180 181 /* 182 * Modify an existing script or add a new script with the specified script 183 * name and contents. If there are no script slots available, an error will 184 * be returned. 185 */ 186 static int 187 db_script_set(const char *scriptname, const char *script) 188 { 189 struct ddb_script *dsp; 190 int error; 191 192 error = db_script_valid(scriptname, script); 193 if (error) 194 return (error); 195 dsp = db_script_lookup(scriptname); 196 if (dsp == NULL) { 197 dsp = db_script_new(); 198 if (dsp == NULL) 199 return (ENOSPC); 200 strlcpy(dsp->ds_scriptname, scriptname, 201 sizeof(dsp->ds_scriptname)); 202 } 203 strlcpy(dsp->ds_script, script, sizeof(dsp->ds_script)); 204 return (0); 205 } 206 207 /* 208 * Delete an existing script by name, if found. 209 */ 210 static int 211 db_script_unset(const char *scriptname) 212 { 213 struct ddb_script *dsp; 214 215 dsp = db_script_lookup(scriptname); 216 if (dsp == NULL) 217 return (ENOENT); 218 strcpy(dsp->ds_scriptname, ""); 219 strcpy(dsp->ds_script, ""); 220 return (0); 221 } 222 223 /* 224 * Trim leading/trailing white space in a command so that we don't pass 225 * carriage returns, etc, into DDB command parser. 226 */ 227 static int 228 db_command_trimmable(char ch) 229 { 230 231 switch (ch) { 232 case ' ': 233 case '\t': 234 case '\n': 235 case '\r': 236 return (1); 237 238 default: 239 return (0); 240 } 241 } 242 243 static void 244 db_command_trim(char **commandp) 245 { 246 char *command; 247 248 command = *commandp; 249 while (db_command_trimmable(*command)) 250 command++; 251 while ((strlen(command) > 0) && 252 db_command_trimmable(command[strlen(command) - 1])) 253 command[strlen(command) - 1] = 0; 254 *commandp = command; 255 } 256 257 /* 258 * Execute a script, breaking it up into individual commands and passing them 259 * sequentially into DDB's input processing. Use the KDB jump buffer to 260 * restore control to the main script loop if things get too wonky when 261 * processing a command -- i.e., traps, etc. Also, make sure we don't exceed 262 * practical limits on recursion. 263 * 264 * XXXRW: If any individual command is too long, it will be truncated when 265 * injected into the input at a lower layer. We should validate the script 266 * before configuring it to avoid this scenario. 267 */ 268 static int 269 db_script_exec(const char *scriptname, int warnifnotfound) 270 { 271 struct db_recursion_data *drd; 272 struct ddb_script *dsp; 273 char *buffer, *command; 274 void *prev_jb; 275 jmp_buf jb; 276 277 dsp = db_script_lookup(scriptname); 278 if (dsp == NULL) { 279 if (warnifnotfound) 280 db_printf("script '%s' not found\n", scriptname); 281 return (ENOENT); 282 } 283 284 if (db_recursion >= DB_MAXSCRIPTRECURSION) { 285 db_printf("Script stack too deep\n"); 286 return (E2BIG); 287 } 288 db_recursion++; 289 drd = &db_recursion_data[db_recursion]; 290 291 /* 292 * Parse script in temporary buffer, since strsep() is destructive. 293 */ 294 buffer = drd->drd_buffer; 295 strcpy(buffer, dsp->ds_script); 296 while ((command = strsep(&buffer, ";")) != NULL) { 297 db_printf("db:%d:%s> %s\n", db_recursion, scriptname, 298 command); 299 db_command_trim(&command); 300 prev_jb = kdb_jmpbuf(jb); 301 if (setjmp(jb) == 0) 302 db_command_script(command); 303 else 304 db_printf("Script command '%s' returned error\n", 305 command); 306 kdb_jmpbuf(prev_jb); 307 } 308 db_recursion--; 309 return (0); 310 } 311 312 /* 313 * Wrapper for exec path that is called on KDB enter. Map reason for KDB 314 * enter to a script name, and don't whine if the script doesn't exist. If 315 * there is no matching script, try the catch-all script. 316 */ 317 void 318 db_script_kdbenter(const char *eventname) 319 { 320 char scriptname[DB_MAXSCRIPTNAME]; 321 322 snprintf(scriptname, sizeof(scriptname), "%s.%s", 323 DB_SCRIPT_KDBENTER_PREFIX, eventname); 324 if (db_script_exec(scriptname, 0) == ENOENT) 325 (void)db_script_exec(DB_SCRIPT_KDBENTER_DEFAULT, 0); 326 } 327 328 /*- 329 * DDB commands for scripting, as reached via the DDB user interface: 330 * 331 * scripts - lists scripts 332 * run <scriptname> - run a script 333 * script <scriptname> - prints script 334 * script <scriptname> <script> - set a script 335 * unscript <scriptname> - remove a script 336 */ 337 338 /* 339 * List scripts and their contents. 340 */ 341 void 342 db_scripts_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, 343 char *modif) 344 { 345 int i; 346 347 for (i = 0; i < DB_MAXSCRIPTS; i++) { 348 if (strlen(db_script_table[i].ds_scriptname) != 0) { 349 db_printf("%s=%s\n", 350 db_script_table[i].ds_scriptname, 351 db_script_table[i].ds_script); 352 } 353 } 354 } 355 356 /* 357 * Execute a script. 358 */ 359 void 360 db_run_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *modif) 361 { 362 int t; 363 364 /* 365 * Right now, we accept exactly one argument. In the future, we 366 * might want to accept flags and arguments to the script itself. 367 */ 368 t = db_read_token(); 369 if (t != tIDENT) 370 db_error("?\n"); 371 372 if (db_read_token() != tEOL) 373 db_error("?\n"); 374 375 db_script_exec(db_tok_string, 1); 376 } 377 378 /* 379 * Print or set a named script, with the set portion broken out into its own 380 * function. We must directly access the remainder of the DDB line input as 381 * we do not wish to use db_lex's token processing. 382 */ 383 void 384 db_script_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, 385 char *modif) 386 { 387 char *buf, scriptname[DB_MAXSCRIPTNAME]; 388 struct ddb_script *dsp; 389 int error, t; 390 391 t = db_read_token(); 392 if (t != tIDENT) { 393 db_printf("usage: script scriptname=script\n"); 394 db_skip_to_eol(); 395 return; 396 } 397 398 if (strlcpy(scriptname, db_tok_string, sizeof(scriptname)) >= 399 sizeof(scriptname)) { 400 db_printf("scriptname too long\n"); 401 db_skip_to_eol(); 402 return; 403 } 404 405 t = db_read_token(); 406 if (t == tEOL) { 407 dsp = db_script_lookup(scriptname); 408 if (dsp == NULL) { 409 db_printf("script '%s' not found\n", scriptname); 410 db_skip_to_eol(); 411 return; 412 } 413 db_printf("%s=%s\n", scriptname, dsp->ds_script); 414 } else if (t == tEQ) { 415 buf = db_get_line(); 416 if (buf[strlen(buf)-1] == '\n') 417 buf[strlen(buf)-1] = '\0'; 418 error = db_script_set(scriptname, buf); 419 if (error != 0) 420 db_printf("Error: %d\n", error); 421 } else 422 db_printf("?\n"); 423 db_skip_to_eol(); 424 } 425 426 /* 427 * Remove a named script. 428 */ 429 void 430 db_unscript_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, 431 char *modif) 432 { 433 int error, t; 434 435 t = db_read_token(); 436 if (t != tIDENT) { 437 db_printf("?\n"); 438 db_skip_to_eol(); 439 return; 440 } 441 442 error = db_script_unset(db_tok_string); 443 if (error == ENOENT) { 444 db_printf("script '%s' not found\n", db_tok_string); 445 db_skip_to_eol(); 446 return; 447 } 448 db_skip_to_eol(); 449 } 450 451 /* 452 * Sysctls for managing DDB scripting: 453 * 454 * debug.ddb.scripting.script - Define a new script 455 * debug.ddb.scripting.scripts - List of names *and* scripts 456 * debug.ddb.scripting.unscript - Remove an existing script 457 * 458 * Since we don't want to try to manage arbitrary extensions to the sysctl 459 * name space from the debugger, the script/unscript sysctls are a bit more 460 * like RPCs and a bit less like normal get/set requests. The ddb(8) command 461 * line tool wraps them to make things a bit more user-friendly. 462 */ 463 static SYSCTL_NODE(_debug_ddb, OID_AUTO, scripting, CTLFLAG_RW, 0, 464 "DDB script settings"); 465 466 static int 467 sysctl_debug_ddb_scripting_scripts(SYSCTL_HANDLER_ARGS) 468 { 469 struct sbuf sb; 470 int error, i, len; 471 char *buffer; 472 473 /* 474 * Make space to include a maximum-length name, = symbol, 475 * maximum-length script, and carriage return for every script that 476 * may be defined. 477 */ 478 len = DB_MAXSCRIPTS * (DB_MAXSCRIPTNAME + 1 + DB_MAXSCRIPTLEN + 1); 479 buffer = malloc(len, M_TEMP, M_WAITOK); 480 (void)sbuf_new(&sb, buffer, len, SBUF_FIXEDLEN); 481 mtx_lock(&db_script_mtx); 482 for (i = 0; i < DB_MAXSCRIPTS; i++) { 483 if (strlen(db_script_table[i].ds_scriptname) == 0) 484 continue; 485 (void)sbuf_printf(&sb, "%s=%s\n", 486 db_script_table[i].ds_scriptname, 487 db_script_table[i].ds_script); 488 } 489 mtx_unlock(&db_script_mtx); 490 sbuf_finish(&sb); 491 error = SYSCTL_OUT(req, sbuf_data(&sb), sbuf_len(&sb) + 1); 492 sbuf_delete(&sb); 493 free(buffer, M_TEMP); 494 return (error); 495 } 496 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, scripts, CTLTYPE_STRING | 497 CTLFLAG_RD, 0, 0, sysctl_debug_ddb_scripting_scripts, "A", 498 "List of defined scripts"); 499 500 static int 501 sysctl_debug_ddb_scripting_script(SYSCTL_HANDLER_ARGS) 502 { 503 char *buffer, *script, *scriptname; 504 int error, len; 505 506 /* 507 * Maximum length for an input string is DB_MAXSCRIPTNAME + '=' 508 * symbol + DB_MAXSCRIPT. 509 */ 510 len = DB_MAXSCRIPTNAME + DB_MAXSCRIPTLEN + 1; 511 buffer = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 512 error = sysctl_handle_string(oidp, buffer, len, req); 513 if (error) 514 goto out; 515 516 /* 517 * Argument will be in form scriptname=script, so split into the 518 * scriptname and script. 519 */ 520 script = buffer; 521 scriptname = strsep(&script, "="); 522 if (script == NULL) { 523 error = EINVAL; 524 goto out; 525 } 526 mtx_lock(&db_script_mtx); 527 error = db_script_set(scriptname, script); 528 mtx_unlock(&db_script_mtx); 529 out: 530 free(buffer, M_TEMP); 531 return (error); 532 } 533 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, script, CTLTYPE_STRING | 534 CTLFLAG_RW, 0, 0, sysctl_debug_ddb_scripting_script, "A", 535 "Set a script"); 536 537 /* 538 * debug.ddb.scripting.unscript has somewhat unusual sysctl semantics -- set 539 * the name of the script that you want to delete. 540 */ 541 static int 542 sysctl_debug_ddb_scripting_unscript(SYSCTL_HANDLER_ARGS) 543 { 544 char name[DB_MAXSCRIPTNAME]; 545 int error; 546 547 bzero(name, sizeof(name)); 548 error = sysctl_handle_string(oidp, name, sizeof(name), req); 549 if (error) 550 return (error); 551 if (req->newptr == NULL) 552 return (0); 553 mtx_lock(&db_script_mtx); 554 error = db_script_unset(name); 555 mtx_unlock(&db_script_mtx); 556 if (error == ENOENT) 557 return (EINVAL); /* Don't confuse sysctl consumers. */ 558 return (0); 559 } 560 SYSCTL_PROC(_debug_ddb_scripting, OID_AUTO, unscript, CTLTYPE_STRING | 561 CTLFLAG_RW, 0, 0, sysctl_debug_ddb_scripting_unscript, "A", 562 "Unset a script"); 563