1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <mdb/mdb_modapi.h> 30 #include <mdb/mdb_ctf.h> 31 32 #include <sys/types.h> 33 #include <sys/regset.h> 34 #include <sys/stack.h> 35 #include <sys/thread.h> 36 37 #include "findstack.h" 38 39 #ifndef STACK_BIAS 40 #define STACK_BIAS 0 41 #endif 42 43 #define fs_dprintf(x) \ 44 if (findstack_debug_on) { \ 45 mdb_printf("findstack debug: "); \ 46 /*CSTYLED*/ \ 47 mdb_printf x ; \ 48 } 49 50 static int findstack_debug_on = 0; 51 52 #if defined(__i386) || defined(__amd64) 53 struct rwindow { 54 uintptr_t rw_fp; 55 uintptr_t rw_pc; 56 }; 57 #endif 58 59 #define TOO_BIG_FOR_A_STACK (1024 * 1024) 60 61 #define KTOU(p) ((p) - kbase + ubase) 62 #define UTOK(p) ((p) - ubase + kbase) 63 64 #if defined(__i386) || defined(__amd64) 65 static GElf_Sym thread_exit_sym; 66 #endif 67 68 #define CRAWL_FOUNDALL (-1) 69 70 /* 71 * Given a stack pointer, try to crawl down it to the bottom. 72 * "frame" is a VA in MDB's address space. 73 * 74 * Returns the number of frames successfully crawled down, or 75 * CRAWL_FOUNDALL if it got to the bottom of the stack. 76 */ 77 static int 78 crawl(uintptr_t frame, uintptr_t kbase, uintptr_t ktop, uintptr_t ubase, 79 int kill_fp) 80 { 81 int levels = 0; 82 83 fs_dprintf(("<0> frame = %p, kbase = %p, ktop = %p, ubase = %p\n", 84 frame, kbase, ktop, ubase)); 85 for (;;) { 86 uintptr_t fp; 87 long *fpp = (long *)&((struct rwindow *)frame)->rw_fp; 88 89 fs_dprintf(("<1> fpp = %p, frame = %p\n", fpp, frame)); 90 91 if ((frame & (STACK_ALIGN - 1)) != 0) 92 break; 93 94 fp = ((struct rwindow *)frame)->rw_fp + STACK_BIAS; 95 fs_dprintf(("<2> fp = %p\n", fp)); 96 97 if (fp == ktop) 98 return (CRAWL_FOUNDALL); 99 fs_dprintf(("<3> not at base\n")); 100 101 #if defined(__i386) || defined(__amd64) 102 if (ktop - fp == sizeof (struct rwindow)) { 103 fs_dprintf(("<4> found base\n")); 104 return (CRAWL_FOUNDALL); 105 } 106 #endif 107 108 fs_dprintf(("<5> fp = %p, kbase = %p, ktop - size = %p\n", 109 fp, kbase, ktop - sizeof (struct rwindow))); 110 111 if (fp < kbase || fp >= (ktop - sizeof (struct rwindow))) 112 break; 113 114 frame = KTOU(fp); 115 fs_dprintf(("<6> frame = %p\n", frame)); 116 117 /* 118 * NULL out the old %fp so we don't go down this stack 119 * more than once. 120 */ 121 if (kill_fp) { 122 fs_dprintf(("<7> fpp = %p\n", fpp)); 123 *fpp = NULL; 124 } 125 126 fs_dprintf(("<8> levels = %d\n", levels)); 127 levels++; 128 } 129 130 return (levels); 131 } 132 133 /* 134 * "sp" is a kernel VA. 135 */ 136 static int 137 print_stack(uintptr_t sp, uintptr_t pc, uintptr_t addr, 138 int argc, const mdb_arg_t *argv, int free_state) 139 { 140 int showargs = 0, count, err; 141 142 count = mdb_getopts(argc, argv, 143 'v', MDB_OPT_SETBITS, TRUE, &showargs, NULL); 144 argc -= count; 145 argv += count; 146 147 if (argc > 1 || (argc == 1 && argv->a_type != MDB_TYPE_STRING)) 148 return (DCMD_USAGE); 149 150 mdb_printf("stack pointer for thread %p%s: %p\n", 151 addr, (free_state ? " (TS_FREE)" : ""), sp); 152 if (pc != 0) 153 mdb_printf("[ %0?lr %a() ]\n", sp, pc); 154 155 mdb_inc_indent(2); 156 mdb_set_dot(sp); 157 158 if (argc == 1) 159 err = mdb_eval(argv->a_un.a_str); 160 else if (showargs) 161 err = mdb_eval("<.$C"); 162 else 163 err = mdb_eval("<.$C0"); 164 165 mdb_dec_indent(2); 166 167 return ((err == -1) ? DCMD_ABORT : DCMD_OK); 168 } 169 170 /*ARGSUSED*/ 171 int 172 findstack(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 173 { 174 kthread_t thr; 175 size_t stksz; 176 uintptr_t ubase, utop; 177 uintptr_t kbase, ktop; 178 uintptr_t win, sp; 179 int free_state; 180 181 if (!(flags & DCMD_ADDRSPEC)) 182 return (DCMD_USAGE); 183 184 bzero(&thr, sizeof (thr)); 185 if (mdb_ctf_vread(&thr, "kthread_t", addr, 186 MDB_CTF_VREAD_IGNORE_ALL) == -1) { 187 mdb_warn("couldn't read thread at %p\n", addr); 188 return (DCMD_ERR); 189 } 190 191 if ((thr.t_schedflag & TS_LOAD) == 0) { 192 mdb_warn("thread %p isn't in memory\n", addr); 193 return (DCMD_ERR); 194 } 195 196 if (thr.t_stk < thr.t_stkbase) { 197 mdb_warn("stack base or stack top corrupt for thread %p\n", 198 addr); 199 return (DCMD_ERR); 200 } 201 202 free_state = thr.t_state == TS_FREE; 203 204 kbase = (uintptr_t)thr.t_stkbase; 205 ktop = (uintptr_t)thr.t_stk; 206 stksz = ktop - kbase; 207 208 #ifdef __amd64 209 /* 210 * The stack on amd64 is intentionally misaligned, so ignore the top 211 * half-frame. See thread_stk_init(). When handling traps, the frame 212 * is automatically aligned by the hardware, so we only alter ktop if 213 * needed. 214 */ 215 if ((ktop & (STACK_ALIGN - 1)) != 0) 216 ktop -= STACK_ENTRY_ALIGN; 217 #endif 218 219 /* 220 * If the stack size is larger than a meg, assume that it's bogus. 221 */ 222 if (stksz > TOO_BIG_FOR_A_STACK) { 223 mdb_warn("stack size for thread %p is too big to be " 224 "reasonable\n", addr); 225 return (DCMD_ERR); 226 } 227 228 /* 229 * This could be (and was) a UM_GC allocation. Unfortunately, 230 * stksz tends to be very large. As currently implemented, dcmds 231 * invoked as part of pipelines don't have their UM_GC-allocated 232 * memory freed until the pipeline completes. With stksz in the 233 * neighborhood of 20k, the popular ::walk thread |::findstack 234 * pipeline can easily run memory-constrained debuggers (kmdb) out 235 * of memory. This can be changed back to a gc-able allocation when 236 * the debugger is changed to free UM_GC memory more promptly. 237 */ 238 ubase = (uintptr_t)mdb_alloc(stksz, UM_SLEEP); 239 utop = ubase + stksz; 240 if (mdb_vread((caddr_t)ubase, stksz, kbase) != stksz) { 241 mdb_free((void *)ubase, stksz); 242 mdb_warn("couldn't read entire stack for thread %p\n", addr); 243 return (DCMD_ERR); 244 } 245 246 /* 247 * Try the saved %sp first, if it looks reasonable. 248 */ 249 sp = KTOU((uintptr_t)thr.t_sp + STACK_BIAS); 250 if (sp >= ubase && sp <= utop) { 251 if (crawl(sp, kbase, ktop, ubase, 0) == CRAWL_FOUNDALL) { 252 mdb_free((void *)ubase, stksz); 253 #if defined(__i386) 254 return (print_stack((uintptr_t)thr.t_sp, 0, addr, 255 argc, argv, free_state)); 256 #else 257 return (print_stack((uintptr_t)thr.t_sp, thr.t_pc, addr, 258 argc, argv, free_state)); 259 #endif 260 } 261 } 262 263 /* 264 * Now walk through the whole stack, starting at the base, 265 * trying every possible "window". 266 */ 267 for (win = ubase; 268 win + sizeof (struct rwindow) <= utop; 269 win += sizeof (struct rwindow *)) { 270 if (crawl(win, kbase, ktop, ubase, 1) == CRAWL_FOUNDALL) { 271 mdb_free((void *)ubase, stksz); 272 return (print_stack(UTOK(win) - STACK_BIAS, 0, addr, 273 argc, argv, free_state)); 274 } 275 } 276 277 /* 278 * We didn't conclusively find the stack. So we'll take another lap, 279 * and print out anything that looks possible. 280 */ 281 mdb_printf("Possible stack pointers for thread %p:\n", addr); 282 (void) mdb_vread((caddr_t)ubase, stksz, kbase); 283 284 for (win = ubase; 285 win + sizeof (struct rwindow) <= utop; 286 win += sizeof (struct rwindow *)) { 287 uintptr_t fp = ((struct rwindow *)win)->rw_fp; 288 int levels; 289 290 if ((levels = crawl(win, kbase, ktop, ubase, 1)) > 1) { 291 mdb_printf(" %p (%d)\n", fp, levels); 292 } else if (levels == CRAWL_FOUNDALL) { 293 /* 294 * If this is a live system, the stack could change 295 * between the two mdb_vread(ubase, utop, kbase)'s, 296 * and we could have a fully valid stack here. 297 */ 298 mdb_free((void *)ubase, stksz); 299 return (print_stack(UTOK(win) - STACK_BIAS, 0, addr, 300 argc, argv, free_state)); 301 } 302 } 303 304 mdb_free((void *)ubase, stksz); 305 return (DCMD_OK); 306 } 307 308 /*ARGSUSED*/ 309 int 310 findstack_debug(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *av) 311 { 312 findstack_debug_on ^= 1; 313 314 mdb_printf("findstack: debugging is now %s\n", 315 findstack_debug_on ? "on" : "off"); 316 317 return (DCMD_OK); 318 } 319 320 int 321 findstack_init(void) 322 { 323 #if defined(__i386) || defined(__amd64) 324 if (mdb_lookup_by_name("thread_exit", &thread_exit_sym) == -1) { 325 mdb_warn("couldn't find 'thread_exit' symbol"); 326 return (DCMD_ABORT); 327 } 328 #endif 329 330 return (DCMD_OK); 331 } 332