Print this page
5554 kmdb can't trace stacks that begin within itself
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>


 191 
 192         mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n",
 193             kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff),
 194             (kregs[KREG_GS] & 0xffff));
 195         mdb_printf("   %%err = 0x%x\n", kregs[KREG_ERR]);
 196 }
 197 
 198 int
 199 mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
 200     mdb_tgt_stack_f *func, void *arg)
 201 {
 202         mdb_tgt_gregset_t gregs;
 203         kreg_t *kregs = &gregs.kregs[0];
 204         int got_pc = (gsp->kregs[KREG_RIP] != 0);
 205         uint_t argc, reg_argc;
 206         long fr_argv[32];
 207         int start_index; /* index to save_instr where to start comparison */
 208         int err;
 209         int i;
 210 
 211         struct {
 212                 uintptr_t fr_savfp;
 213                 uintptr_t fr_savpc;
 214         } fr;
 215 
 216         uintptr_t fp = gsp->kregs[KREG_RBP];
 217         uintptr_t pc = gsp->kregs[KREG_RIP];
 218         uintptr_t lastfp = 0;
 219 
 220         ssize_t size;
 221         ssize_t insnsize;
 222         uint8_t ins[SAVEARGS_INSN_SEQ_LEN];
 223 
 224         GElf_Sym s;
 225         mdb_syminfo_t sip;
 226         mdb_ctf_funcinfo_t mfp;
 227         int xpv_panic = 0;


 228 #ifndef _KMDB
 229         int xp;
 230 
 231         if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0))
 232                 xpv_panic = 1;
 233 #endif
 234 
 235         bcopy(gsp, &gregs, sizeof (gregs));
 236 
 237         while (fp != 0) {
 238                 int args_style = 0;
 239 
 240                 /*
 241                  * Ensure progress (increasing fp), and prevent
 242                  * endless loop with the same FP.
 243                  */
 244                 if (fp <= lastfp) {
 245                         err = EMDB_STKFRAME;
 246                         goto badfp;
 247                 }
 248                 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) {








 249                         err = EMDB_NOMAP;
 250                         goto badfp;
 251                 }
 252 











 253                 if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY,
 254                     NULL, 0, &s, &sip) == 0) &&
 255                     (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) {
 256                         int return_type = mdb_ctf_type_kind(mfp.mtf_return);
 257                         mdb_ctf_id_t args_types[5];
 258 
 259                         argc = mfp.mtf_argc;
 260 
 261                         /*
 262                          * If the function returns a structure or union
 263                          * greater than 16 bytes in size %rdi contains the
 264                          * address in which to store the return value rather
 265                          * than for an argument.
 266                          */
 267                         if ((return_type == CTF_K_STRUCT ||
 268                             return_type == CTF_K_UNION) &&
 269                             mdb_ctf_type_size(mfp.mtf_return) > 16)
 270                                 start_index = 1;
 271                         else
 272                                 start_index = 0;




 191 
 192         mdb_printf("%%trapno = 0x%x\t\t%%fs = 0x%04x\t%%gs = 0x%04x\n",
 193             kregs[KREG_TRAPNO], (kregs[KREG_FS] & 0xffff),
 194             (kregs[KREG_GS] & 0xffff));
 195         mdb_printf("   %%err = 0x%x\n", kregs[KREG_ERR]);
 196 }
 197 
 198 int
 199 mdb_amd64_kvm_stack_iter(mdb_tgt_t *t, const mdb_tgt_gregset_t *gsp,
 200     mdb_tgt_stack_f *func, void *arg)
 201 {
 202         mdb_tgt_gregset_t gregs;
 203         kreg_t *kregs = &gregs.kregs[0];
 204         int got_pc = (gsp->kregs[KREG_RIP] != 0);
 205         uint_t argc, reg_argc;
 206         long fr_argv[32];
 207         int start_index; /* index to save_instr where to start comparison */
 208         int err;
 209         int i;
 210 
 211         struct fr {
 212                 uintptr_t fr_savfp;
 213                 uintptr_t fr_savpc;
 214         } fr;
 215 
 216         uintptr_t fp = gsp->kregs[KREG_RBP];
 217         uintptr_t pc = gsp->kregs[KREG_RIP];
 218         uintptr_t lastfp = 0;
 219 
 220         ssize_t size;
 221         ssize_t insnsize;
 222         uint8_t ins[SAVEARGS_INSN_SEQ_LEN];
 223 
 224         GElf_Sym s;
 225         mdb_syminfo_t sip;
 226         mdb_ctf_funcinfo_t mfp;
 227         int xpv_panic = 0;
 228         int advance_tortoise = 1;
 229         uintptr_t tortoise_fp = 0;
 230 #ifndef _KMDB
 231         int xp;
 232 
 233         if ((mdb_readsym(&xp, sizeof (xp), "xpv_panicking") != -1) && (xp > 0))
 234                 xpv_panic = 1;
 235 #endif
 236 
 237         bcopy(gsp, &gregs, sizeof (gregs));
 238 
 239         while (fp != 0) {
 240                 int args_style = 0;
 241 
 242                 if (mdb_tgt_vread(t, &fr, sizeof (fr), fp) != sizeof (fr)) {
 243                         err = EMDB_NOMAP;




 244                         goto badfp;
 245                 }
 246 
 247                 if (tortoise_fp == 0) {
 248                         tortoise_fp = fp;
 249                 } else {
 250                         if (advance_tortoise != 0) {
 251                                 struct fr tfr;
 252 
 253                                 if (mdb_tgt_vread(t, &tfr, sizeof (tfr),
 254                                     tortoise_fp) != sizeof (tfr)) {
 255                                         err = EMDB_NOMAP;
 256                                         goto badfp;
 257                                 }
 258 
 259                                 tortoise_fp = tfr.fr_savfp;
 260                         }
 261 
 262                         if (fp == tortoise_fp) {
 263                                 err = EMDB_STKFRAME;
 264                                 goto badfp;
 265                         }
 266                 }
 267 
 268                 advance_tortoise = !advance_tortoise;
 269 
 270                 if ((mdb_tgt_lookup_by_addr(t, pc, MDB_TGT_SYM_FUZZY,
 271                     NULL, 0, &s, &sip) == 0) &&
 272                     (mdb_ctf_func_info(&s, &sip, &mfp) == 0)) {
 273                         int return_type = mdb_ctf_type_kind(mfp.mtf_return);
 274                         mdb_ctf_id_t args_types[5];
 275 
 276                         argc = mfp.mtf_argc;
 277 
 278                         /*
 279                          * If the function returns a structure or union
 280                          * greater than 16 bytes in size %rdi contains the
 281                          * address in which to store the return value rather
 282                          * than for an argument.
 283                          */
 284                         if ((return_type == CTF_K_STRUCT ||
 285                             return_type == CTF_K_UNION) &&
 286                             mdb_ctf_type_size(mfp.mtf_return) > 16)
 287                                 start_index = 1;
 288                         else
 289                                 start_index = 0;