Print this page
12364 mdb trips assertion related to autowrap
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mdb/common/mdb/mdb_set.c
+++ new/usr/src/cmd/mdb/common/mdb/mdb_set.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 - * Copyright 2017 Joyent, Inc.
27 + * Copyright 2020 Joyent, Inc.
28 28 */
29 29
30 30 /*
31 31 * Support for ::set dcmd. The +/-o option processing code is provided in a
32 32 * stand-alone function so it can be used by the command-line option processing
33 33 * code in mdb_main.c. This facility provides an easy way for us to add more
34 34 * configurable options without having to add a new dcmd each time.
35 35 */
36 36
37 37 #include <mdb/mdb_target.h>
38 38 #include <mdb/mdb_modapi.h>
39 39 #include <mdb/mdb_string.h>
40 40 #include <mdb/mdb_debug.h>
41 41 #include <mdb/mdb.h>
42 42
43 43 /*ARGSUSED*/
44 44 static int
45 45 opt_set_mflags(int enable, uint_t bits, const char *arg)
46 46 {
47 47 mdb.m_flags = (mdb.m_flags & ~bits) | (bits & -enable);
48 48 return (1);
49 49 }
50 50
51 51 /*ARGSUSED*/
52 52 static int
53 53 opt_set_tflags(int enable, uint_t bits, const char *arg)
54 54 {
55 55 mdb.m_tgtflags = (mdb.m_tgtflags & ~bits) | (bits & -enable);
56 56 return (1);
57 57 }
58 58
59 59 static int
60 60 opt_pager(int enable, uint_t bits, const char *arg)
61 61 {
62 62 if (enable)
63 63 mdb_iob_setflags(mdb.m_out, MDB_IOB_PGENABLE);
64 64 else
65 65 mdb_iob_clrflags(mdb.m_out, MDB_IOB_PGENABLE);
66 66
67 67 return (opt_set_mflags(enable, bits, arg));
68 68 }
69 69
70 70 static int
71 71 opt_adb(int enable, uint_t bits, const char *arg)
72 72 {
73 73 if (enable)
74 74 (void) mdb_set_prompt("");
75 75 else if (mdb.m_promptlen == 0)
76 76 (void) mdb_set_prompt("> ");
77 77
78 78 (void) opt_pager(1 - enable, MDB_FL_PAGER, arg);
79 79 return (opt_set_mflags(enable, bits, arg));
80 80 }
81 81
82 82 /*ARGSUSED*/
83 83 static int
84 84 opt_armemlim(int enable, uint_t bits, const char *arg)
85 85 {
86 86 if (strisnum(arg)) {
87 87 mdb.m_armemlim = strtoi(arg);
88 88 return (1);
89 89 }
90 90 if (strcmp(arg, "none") == 0) {
91 91 mdb.m_armemlim = MDB_ARR_NOLIMIT;
92 92 return (1);
93 93 }
94 94 return (0);
95 95 }
96 96
97 97 /*ARGSUSED*/
98 98 static int
99 99 opt_arstrlim(int enable, uint_t bits, const char *arg)
100 100 {
101 101 if (strisnum(arg)) {
102 102 mdb.m_arstrlim = strtoi(arg);
103 103 return (1);
104 104 }
105 105 if (strcmp(arg, "none") == 0) {
106 106 mdb.m_arstrlim = MDB_ARR_NOLIMIT;
107 107 return (1);
108 108 }
109 109 return (0);
110 110 }
111 111
112 112 /*ARGSUSED*/
113 113 static int
114 114 opt_exec_mode(int enable, uint_t bits, const char *arg)
115 115 {
116 116 if (strcmp(arg, "ask") == 0) {
117 117 mdb.m_execmode = MDB_EM_ASK;
118 118 return (1);
119 119 } else if (strcmp(arg, "stop") == 0) {
120 120 mdb.m_execmode = MDB_EM_STOP;
121 121 return (1);
122 122 } else if (strcmp(arg, "follow") == 0) {
123 123 mdb.m_execmode = MDB_EM_FOLLOW;
124 124 return (1);
125 125 }
126 126 return (0);
127 127 }
128 128
129 129 /*ARGSUSED*/
130 130 static int
131 131 opt_fork_mode(int enable, uint_t bits, const char *arg)
132 132 {
133 133 if (strcmp(arg, "ask") == 0) {
134 134 mdb.m_forkmode = MDB_FM_ASK;
135 135 return (1);
136 136 } else if (strcmp(arg, "parent") == 0) {
137 137 mdb.m_forkmode = MDB_FM_PARENT;
138 138 return (1);
139 139 } else if (strcmp(arg, "child") == 0) {
140 140 mdb.m_forkmode = MDB_FM_CHILD;
141 141 return (1);
142 142 }
143 143 return (0);
144 144 }
145 145
146 146 /*ARGSUSED*/
147 147 static int
148 148 opt_set_term(int enable, uint_t bits, const char *arg)
149 149 {
150 150 mdb.m_termtype = strdup(arg);
151 151 mdb.m_flags &= ~MDB_FL_TERMGUESS;
152 152
153 153 return (1);
154 154 }
155 155
156 156 int
157 157 mdb_set_options(const char *s, int enable)
158 158 {
159 159 static const struct opdesc {
160 160 const char *opt_name;
161 161 int (*opt_func)(int, uint_t, const char *);
162 162 uint_t opt_bits;
163 163 } opdtab[] = {
164 164 { "adb", opt_adb, MDB_FL_REPLAST | MDB_FL_NOMODS | MDB_FL_ADB },
165 165 { "array_mem_limit", opt_armemlim, 0 },
166 166 { "array_str_limit", opt_arstrlim, 0 },
167 167 { "follow_exec_mode", opt_exec_mode, 0 },
168 168 { "follow_fork_mode", opt_fork_mode, 0 },
169 169 { "pager", opt_pager, MDB_FL_PAGER },
170 170 { "term", opt_set_term, 0 },
171 171
172 172 { "autowrap", opt_set_mflags, MDB_FL_AUTOWRAP },
173 173 { "ignoreeof", opt_set_mflags, MDB_FL_IGNEOF },
174 174 { "repeatlast", opt_set_mflags, MDB_FL_REPLAST },
175 175 { "latest", opt_set_mflags, MDB_FL_LATEST },
176 176 { "noctf", opt_set_mflags, MDB_FL_NOCTF },
177 177 { "nomods", opt_set_mflags, MDB_FL_NOMODS },
178 178 { "showlmid", opt_set_mflags, MDB_FL_SHOWLMID },
179 179 { "lmraw", opt_set_mflags, MDB_FL_LMRAW },
180 180 { "stop_on_bpt_nosym", opt_set_mflags, MDB_FL_BPTNOSYMSTOP },
181 181 { "write_readback", opt_set_mflags, MDB_FL_READBACK },
182 182
183 183 { "allow_io_access", opt_set_tflags, MDB_TGT_F_ALLOWIO },
184 184 { "nostop", opt_set_tflags, MDB_TGT_F_NOSTOP },
185 185 { NULL, NULL, 0 }
186 186 };
187 187
188 188 const struct opdesc *opp;
189 189 char *buf = strdup(s);
190 190 char *opt, *arg;
191 191 int status = 1;
192 192
193 193 for (opt = strtok(buf, ","); opt != NULL; opt = strtok(NULL, ",")) {
194 194 if ((arg = strchr(opt, '=')) != NULL)
195 195 *arg++ = '\0';
196 196
197 197 for (opp = opdtab; opp->opt_name != NULL; opp++) {
198 198 if (strcmp(opt, opp->opt_name) == 0) {
199 199 if (opp->opt_bits != 0 && arg != NULL) {
200 200 mdb_warn("option does not accept an "
201 201 "argument -- %s\n", opt);
202 202 status = 0;
203 203 } else if (opp->opt_bits == 0 && arg == NULL) {
204 204 mdb_warn("option requires an argument "
205 205 "-- %s\n", opt);
206 206 status = 0;
207 207 } else if (opp->opt_func(enable != 0,
208 208 opp->opt_bits, arg) == 0) {
209 209 mdb_warn("invalid argument for option "
210 210 "%s -- %s\n", opt, arg);
211 211 status = 0;
212 212 }
213 213 break;
214 214 }
215 215 }
216 216
217 217 if (opp->opt_name == NULL) {
218 218 mdb_warn("invalid debugger option -- %s\n", opt);
219 219 status = 0;
220 220 }
221 221 }
222 222
223 223 mdb_free(buf, strlen(s) + 1);
224 224 return (status);
225 225 }
226 226
227 227 static void
228 228 print_path(const char **path, int indent)
229 229 {
230 230 if (path != NULL && *path != NULL) {
231 231 for (mdb_printf("%s\n", *path++); *path != NULL; path++)
232 232 mdb_printf("%*s%s\n", indent, " ", *path);
233 233 }
234 234 mdb_printf("\n");
235 235 }
236 236
237 237 #define LABEL_INDENT 26
238 238
239 239 static void
240 240 print_properties(void)
241 241 {
242 242 int tflags = mdb_tgt_getflags(mdb.m_target);
243 243 uint_t oflags = mdb_iob_getflags(mdb.m_out) & MDB_IOB_AUTOWRAP;
244 244
245 245 mdb_iob_clrflags(mdb.m_out, MDB_IOB_AUTOWRAP);
246 246 mdb_printf("\n macro path: ");
247 247 print_path(mdb.m_ipath, 14);
248 248 mdb_printf(" module path: ");
249 249 print_path(mdb.m_lpath, 14);
250 250 mdb_iob_setflags(mdb.m_out, oflags);
251 251
252 252 mdb_printf("%*s %lr (%s)\n", LABEL_INDENT, "symbol matching distance:",
253 253 mdb.m_symdist, mdb.m_symdist ? "absolute mode" : "smart mode");
254 254
255 255 mdb_printf("%*s ", LABEL_INDENT, "array member print limit:");
256 256 if (mdb.m_armemlim != MDB_ARR_NOLIMIT)
257 257 mdb_printf("%u\n", mdb.m_armemlim);
258 258 else
259 259 mdb_printf("none\n");
260 260
261 261 mdb_printf(" array string print limit: ");
262 262 if (mdb.m_arstrlim != MDB_ARR_NOLIMIT)
263 263 mdb_printf("%u\n", mdb.m_arstrlim);
264 264 else
265 265 mdb_printf("none\n");
266 266
267 267 mdb_printf("%*s \"%s\"\n", LABEL_INDENT, "command prompt:",
↓ open down ↓ |
230 lines elided |
↑ open up ↑ |
268 268 mdb.m_prompt);
269 269
270 270 mdb_printf("%*s ", LABEL_INDENT, "debugger options:");
271 271 (void) mdb_inc_indent(LABEL_INDENT + 1);
272 272
273 273 /*
274 274 * The ::set output implicitly relies on "autowrap" being enabled, so
275 275 * we enable it for the duration of the command.
276 276 */
277 277 oflags = mdb.m_flags;
278 - mdb.m_flags |= MDB_FL_AUTOWRAP;
278 + mdb_iob_set_autowrap(mdb.m_out);
279 279
280 280 mdb_printf("follow_exec_mode=");
281 281 switch (mdb.m_execmode) {
282 282 case MDB_EM_ASK:
283 283 mdb_printf("ask");
284 284 break;
285 285 case MDB_EM_STOP:
286 286 mdb_printf("stop");
287 287 break;
288 288 case MDB_EM_FOLLOW:
289 289 mdb_printf("follow");
290 290 break;
291 291 }
292 292
293 293 #define COMMAFLAG(name) { mdb_printf(", "); mdb_printf(name); }
294 294
295 295 COMMAFLAG("follow_fork_mode");
296 296 switch (mdb.m_forkmode) {
297 297 case MDB_FM_ASK:
298 298 mdb_printf("ask");
299 299 break;
300 300 case MDB_FM_PARENT:
301 301 mdb_printf("parent");
302 302 break;
303 303 case MDB_FM_CHILD:
304 304 mdb_printf("child");
305 305 break;
306 306 }
307 307
308 308 if (mdb.m_flags & MDB_FL_ADB)
309 309 COMMAFLAG("adb");
310 310 if (oflags & MDB_FL_AUTOWRAP)
311 311 COMMAFLAG("autowrap");
312 312 if (mdb.m_flags & MDB_FL_IGNEOF)
313 313 COMMAFLAG("ignoreeof");
314 314 if (mdb.m_flags & MDB_FL_LMRAW)
315 315 COMMAFLAG("lmraw");
316 316 if (mdb.m_flags & MDB_FL_PAGER)
317 317 COMMAFLAG("pager");
318 318 if (mdb.m_flags & MDB_FL_REPLAST)
319 319 COMMAFLAG("repeatlast");
320 320 if (mdb.m_flags & MDB_FL_SHOWLMID)
321 321 COMMAFLAG("showlmid");
322 322 if (mdb.m_flags & MDB_FL_BPTNOSYMSTOP)
323 323 COMMAFLAG("stop_on_bpt_nosym");
324 324 if (mdb.m_flags & MDB_FL_READBACK)
325 325 COMMAFLAG("write_readback");
326 326 mdb_printf("\n");
327 327 (void) mdb_dec_indent(LABEL_INDENT + 1);
328 328
329 329 mdb_printf("%*s ", LABEL_INDENT, "target options:");
330 330 (void) mdb_inc_indent(LABEL_INDENT + 1);
331 331
332 332 if (tflags & MDB_TGT_F_RDWR)
333 333 mdb_printf("read-write");
334 334 else
335 335 mdb_printf("read-only");
336 336 if (tflags & MDB_TGT_F_ALLOWIO)
337 337 COMMAFLAG("allow-io-access");
338 338 if (tflags & MDB_TGT_F_FORCE)
339 339 COMMAFLAG("force-attach");
340 340 if (tflags & MDB_TGT_F_PRELOAD)
341 341 COMMAFLAG("preload-syms");
342 342 if (tflags & MDB_TGT_F_NOLOAD)
343 343 COMMAFLAG("no-load-objs");
344 344 if (tflags & MDB_TGT_F_NOSTOP)
345 345 COMMAFLAG("no-stop");
346 346 mdb_printf("\n");
347 347 (void) mdb_dec_indent(LABEL_INDENT + 1);
348 348
349 349 mdb.m_flags = oflags;
350 350 }
351 351
352 352 /*ARGSUSED*/
353 353 int
354 354 cmd_set(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
355 355 {
356 356 const char *opt_I = NULL, *opt_L = NULL, *opt_P = NULL, *opt_o = NULL;
357 357 const char *opt_plus_o = NULL, *opt_D = NULL;
358 358 uint_t opt_w = FALSE, opt_plus_w = FALSE, opt_W = FALSE;
359 359 uint_t opt_plus_W = FALSE, opt_F = FALSE;
360 360 uintptr_t opt_s = (uintptr_t)(long)-1;
361 361
362 362 int tflags = 0;
363 363 int i;
364 364
365 365 if (flags & DCMD_ADDRSPEC)
366 366 return (DCMD_USAGE);
367 367
368 368 /*
369 369 * If no options are specified, print out the current set of target
370 370 * and debugger properties that can be modified with ::set.
371 371 */
372 372 if (argc == 0) {
373 373 print_properties();
374 374 return (DCMD_OK);
375 375 }
376 376
377 377 while ((i = mdb_getopts(argc, argv,
378 378 'F', MDB_OPT_SETBITS, TRUE, &opt_F,
379 379 'I', MDB_OPT_STR, &opt_I,
380 380 'L', MDB_OPT_STR, &opt_L,
381 381 'P', MDB_OPT_STR, &opt_P,
382 382 'o', MDB_OPT_STR, &opt_o,
383 383 's', MDB_OPT_UINTPTR, &opt_s,
384 384 'w', MDB_OPT_SETBITS, TRUE, &opt_w,
385 385 'W', MDB_OPT_SETBITS, TRUE, &opt_W,
386 386 'D', MDB_OPT_STR, &opt_D, NULL)) != argc) {
387 387 uint_t n = 1;
388 388
389 389 argv += i; /* skip past args we processed */
390 390 argc -= i; /* adjust argc */
391 391
392 392 if (argv[0].a_type != MDB_TYPE_STRING)
393 393 return (DCMD_USAGE);
394 394
395 395 if (strcmp(argv->a_un.a_str, "+W") == 0)
396 396 opt_plus_W = TRUE;
397 397 else if (strcmp(argv->a_un.a_str, "+w") == 0)
398 398 opt_plus_w = TRUE;
399 399 else if (strcmp(argv->a_un.a_str, "+o") == 0 &&
400 400 argc >= 2 && argv[1].a_type == MDB_TYPE_STRING) {
401 401 opt_plus_o = argv[1].a_un.a_str;
402 402 n = 2;
403 403 } else
404 404 return (DCMD_USAGE);
405 405
406 406 /* remove the flag and possible argument */
407 407 argv += n;
408 408 argc -= n;
409 409 }
410 410
411 411 if ((opt_w && opt_plus_w) || (opt_W && opt_plus_W))
412 412 return (DCMD_USAGE);
413 413
414 414 /*
415 415 * Handle -w, -/+W and -F first: as these options modify the target,
416 416 * they are the only ::set changes that can potentially fail. We'll
417 417 * use these flags to modify a copy of the target's t_flags, which we'll
418 418 * then pass to the target's setflags op. This allows the target to
419 419 * detect newly-set and newly-cleared flags by comparing the passed
420 420 * value to the current t_flags.
421 421 */
422 422 tflags = mdb_tgt_getflags(mdb.m_target);
423 423
424 424 if (opt_w)
425 425 tflags |= MDB_TGT_F_RDWR;
426 426 if (opt_plus_w)
427 427 tflags &= ~MDB_TGT_F_RDWR;
428 428 if (opt_W)
429 429 tflags |= MDB_TGT_F_ALLOWIO;
430 430 if (opt_plus_W)
431 431 tflags &= ~MDB_TGT_F_ALLOWIO;
432 432 if (opt_F)
433 433 tflags |= MDB_TGT_F_FORCE;
434 434
435 435 if (tflags != mdb_tgt_getflags(mdb.m_target) &&
436 436 mdb_tgt_setflags(mdb.m_target, tflags) == -1)
437 437 return (DCMD_ERR);
438 438
439 439 /*
440 440 * Now handle everything that either can't fail or we don't care if
441 441 * it does. Note that we handle +/-o first in case another option
442 442 * overrides a change made implicity by a +/-o argument (e.g. -P).
443 443 */
444 444 if (opt_o != NULL)
445 445 (void) mdb_set_options(opt_o, TRUE);
446 446 if (opt_plus_o != NULL)
447 447 (void) mdb_set_options(opt_plus_o, FALSE);
448 448 if (opt_I != NULL) {
449 449 #ifdef _KMDB
450 450 mdb_warn("macro path cannot be set under kmdb\n");
451 451 #else
452 452 mdb_set_ipath(opt_I);
453 453 #endif
454 454 }
455 455 if (opt_L != NULL)
456 456 mdb_set_lpath(opt_L);
457 457 if (opt_P != NULL)
458 458 (void) mdb_set_prompt(opt_P);
459 459 if (opt_s != (uintptr_t)-1)
460 460 mdb.m_symdist = (size_t)opt_s;
461 461 if (opt_D != NULL && (i = mdb_dstr2mode(opt_D)) != MDB_DBG_HELP)
462 462 mdb_dmode((uint_t)i);
463 463
464 464 return (DCMD_OK);
465 465 }
↓ open down ↓ |
177 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX