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