On Wed, Nov 15, 2006 at 10:05:35AM -0500, Dave Anderson wrote: > > Hi Rachita, > > Great -- I'll tinker with this today and get out a new release ASAP. > > One question re: this hanging thread: > > > > So, in other words, if we hardwire the user_regs_struct so that > > > it uses the NT_PRSTATUS registers all the time, then we get > > > the second (preferred/better) budget back trace when unwind > > > is off. > > > > > > That being the case, I argue for hardwiring them all the time. > > > > Yes, we can(should) do that for all the active tasks. > > > > Rachita > > > > Correct me if I'm wrong here, but... > > If, during machdep_init(POST_GBD), if we force-initialize > (hardwire when necessary) the relevant user_regs_struct items, Hi Dave Yes, this should serve the purpose. Thanks Rachita > then we could change this line from: > > if (((NETDUMP_DUMPFILE() || KDUMP_DUMPFILE()) && > VALID_STRUCT(user_regs_struct) && (bt->task == tt->panic_task)) || > (KDUMP_DUMPFILE() && (kt->flags & DWARF_UNWIND) && > (bt->flags & BT_DUMPFILE_SEARCH))) { > to: > > if (((NETDUMP_DUMPFILE() || KDUMP_DUMPFILE()) && > VALID_STRUCT(user_regs_struct) && (bt->task == tt->panic_task)) || > (KDUMP_DUMPFILE() && (bt->flags & BT_DUMPFILE_SEARCH))) { > > To be absolutely safe in a backwards-compatibility sense, perhaps > we should only do the hardwiring if it's a KDUMP_DUMPFILE(). > Make sense? > > Dave > > > > > > > > > > > > defs.h | 3 > > unwind_x86_32_64.c | 77 ++++++++++++++++++++++--- > > x86_64.c | 163 ++++++----------------------------------------------- > > 3 files changed, 91 insertions(+), 152 deletions(-) > > > > diff -puN x86_64.c~cfi_backtrace_minor_fixes x86_64.c > > --- crash-4.0-3.9/x86_64.c~cfi_backtrace_minor_fixes 2006-11-15 18:29:04.848359480 +0530 > > +++ crash-4.0-3.9-rachita/x86_64.c 2006-11-15 19:00:40.687148176 +0530 > > @@ -2548,6 +2548,7 @@ x86_64_dwarf_back_trace_cmd(struct bt_in > > irq_eframe = 0; > > last_process_stack_eframe = 0; > > bt->call_target = NULL; > > + bt->bptr = 0; > > rsp = bt->stkptr; > > if (!rsp) { > > error(INFO, "cannot determine starting stack pointer\n"); > > @@ -2617,31 +2618,9 @@ in_exception_stack: > > > > stacktop = bt->stacktop - SIZE(pt_regs); > > > > - if ((kt->flags & DWARF_UNWIND) && !done) > > - done = dwarf_backtrace(bt, stacktop); > > - > > - for (i = (rsp - bt->stackbase)/sizeof(ulong); > > - !done && (rsp < stacktop); i++, rsp += sizeof(ulong)) { > > - > > - up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); > > - > > - if (!is_kernel_text(*up)) > > - continue; > > - > > - switch (x86_64_print_stack_entry(bt, ofp, level, i,*up)) > > - { > > - case BACKTRACE_ENTRY_AND_EFRAME_DISPLAYED: > > - rsp += SIZE(pt_regs); > > - i += SIZE(pt_regs)/sizeof(ulong); > > - case BACKTRACE_ENTRY_DISPLAYED: > > - level++; > > - break; > > - case BACKTRACE_ENTRY_IGNORED: > > - break; > > - case BACKTRACE_COMPLETE: > > - done = TRUE; > > - break; > > - } > > + if ((kt->flags & DWARF_UNWIND) && !done) { > > + level = dwarf_backtrace(bt, level, stacktop); > > + done = TRUE; > > } > > > > cs = x86_64_exception_frame(EFRAME_PRINT|EFRAME_CS, 0, > > @@ -2702,32 +2681,10 @@ in_exception_stack: > > > > stacktop = bt->stacktop - 64; /* from kernel code */ > > > > - if ((kt->flags & DWARF_UNWIND) && !done) > > - done = dwarf_backtrace(bt, stacktop); > > - > > - for (i = (rsp - bt->stackbase)/sizeof(ulong); > > - !done && (rsp < stacktop); i++, rsp += sizeof(ulong)) { > > - > > - up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); > > - > > - if (!is_kernel_text(*up)) > > - continue; > > - > > - switch (x86_64_print_stack_entry(bt, ofp, level, i,*up)) > > - { > > - case BACKTRACE_ENTRY_AND_EFRAME_DISPLAYED: > > - rsp += SIZE(pt_regs); > > - i += SIZE(pt_regs)/sizeof(ulong); > > - case BACKTRACE_ENTRY_DISPLAYED: > > - level++; > > - break; > > - case BACKTRACE_ENTRY_IGNORED: > > - break; > > - case BACKTRACE_COMPLETE: > > - done = TRUE; > > - break; > > - } > > - } > > + if ((kt->flags & DWARF_UNWIND) && !done) { > > + level = dwarf_backtrace(bt, level, stacktop); > > + done = TRUE; > > + } > > > > if (!BT_REFERENCE_CHECK(bt)) > > fprintf(fp, "--- <IRQ stack> ---\n"); > > @@ -2792,21 +2749,6 @@ in_exception_stack: > > } > > > > /* > > - * For a normally blocked task, hand-create the first level. > > - */ > > - if (!done && !(kt->flags & DWARF_UNWIND) && > > - !(bt->flags & (BT_TEXT_SYMBOLS|BT_EXCEPTION_STACK|BT_IRQSTACK)) && > > - STREQ(closest_symbol(bt->instptr), "thread_return")) { > > - bt->flags |= BT_SCHEDULE; > > - i = (rsp - bt->stackbase)/sizeof(ulong); > > - x86_64_print_stack_entry(bt, ofp, level, > > - i, bt->instptr); > > - bt->flags &= ~(ulonglong)BT_SCHEDULE; > > - rsp += sizeof(ulong); > > - level++; > > - } > > - > > - /* > > * Dump the IRQ exception frame from the process stack. > > * If the CS register indicates a user exception frame, > > * then set done to TRUE to avoid the process stack walk-through. > > @@ -2814,8 +2756,7 @@ in_exception_stack: > > */ > > if (irq_eframe) { > > bt->flags |= BT_EXCEPTION_FRAME; > > - i = (irq_eframe - bt->stackbase)/sizeof(ulong); > > - x86_64_print_stack_entry(bt, ofp, level, i, bt->instptr); > > + level = dwarf_print_stack_entry(bt, level); > > bt->flags &= ~(ulonglong)BT_EXCEPTION_FRAME; > > cs = x86_64_exception_frame(EFRAME_PRINT|EFRAME_CS, 0, > > bt->stackbuf + (irq_eframe - bt->stackbase), bt, ofp); > > @@ -2833,81 +2774,10 @@ in_exception_stack: > > /* > > * Walk the process stack. > > */ > > - if ((kt->flags & DWARF_UNWIND) && !done) > > - done = dwarf_backtrace(bt, bt->stacktop); > > - > > - for (i = (rsp - bt->stackbase)/sizeof(ulong); > > - !done && (rsp < bt->stacktop); i++, rsp += sizeof(ulong)) { > > - > > - up = (ulong *)(&bt->stackbuf[i*sizeof(ulong)]); > > - > > - if (!is_kernel_text(*up)) > > - continue; > > - > > - if ((bt->flags & BT_CHECK_CALLER)) { > > - /* > > - * A non-zero offset value from the value_search() > > - * lets us know if it's a real text return address. > > - */ > > - spt = value_search(*up, &offset); > > - /* > > - * sp gets the syment of the function that the text > > - * routine above called before leaving its return > > - * address on the stack -- if it can be determined. > > - */ > > - sp = x86_64_function_called_by((*up)-5); > > - > > - if (sp == NULL) { > > - /* > > - * We were unable to get the called function. > > - * If the text address had an offset, then > > - * it must have made an indirect call, and > > - * can't have called our target function. > > - */ > > - if (offset) { > > - if (CRASHDEBUG(1)) > > - fprintf(ofp, > > - "< ignoring %s() -- makes indirect call and NOT %s()>\n", > > - spt->name, > > - bt->call_target); > > - continue; > > - } > > - } else if ((machdep->flags & SCHED_TEXT) && > > - STREQ(bt->call_target, "schedule") && > > - STREQ(sp->name, "__sched_text_start")) { > > - ; /* bait and switch */ > > - } else if (!STREQ(sp->name, bt->call_target)) { > > - /* > > - * We got function called by the text routine, > > - * but it's not our target function. > > - */ > > - if (CRASHDEBUG(2)) > > - fprintf(ofp, > > - "< ignoring %s() -- calls %s() and NOT %s()>\n", > > - spt->name, sp->name, > > - bt->call_target); > > - continue; > > - } > > - } > > - > > - switch (x86_64_print_stack_entry(bt, ofp, level, i,*up)) > > - { > > - case BACKTRACE_ENTRY_AND_EFRAME_DISPLAYED: > > - last_process_stack_eframe = rsp + 8; > > - if (x86_64_print_eframe_location(last_process_stack_eframe, level, ofp)) > > - level++; > > - rsp += SIZE(pt_regs); > > - i += SIZE(pt_regs)/sizeof(ulong); > > - case BACKTRACE_ENTRY_DISPLAYED: > > - level++; > > - break; > > - case BACKTRACE_ENTRY_IGNORED: > > - break; > > - case BACKTRACE_COMPLETE: > > - done = TRUE; > > - break; > > - } > > - } > > + if ((kt->flags & DWARF_UNWIND) && !done) { > > + level = dwarf_backtrace(bt, level, bt->stacktop); > > + done = TRUE; > > + } > > > > if (!irq_eframe && !is_kernel_thread(bt->tc->task) && > > (GET_STACKBASE(bt->tc->task) == bt->stackbase)) { > > @@ -3193,6 +3063,13 @@ x86_64_exception_frame(ulong flags, ulon > > x86_64_do_bt_reference_check(bt, r15, NULL); > > } > > > > + /* Remember the rip and rsp for unwinding the process stack */ > > + if (kt->flags & DWARF_UNWIND){ > > + bt->instptr = rip; > > + bt->stkptr = rsp; > > + bt->bptr = rbp; > > + } > > + > > if (kvaddr) > > FREEBUF(pt_regs_buf); > > > > diff -puN unwind_x86_32_64.c~cfi_backtrace_minor_fixes unwind_x86_32_64.c > > --- crash-4.0-3.9/unwind_x86_32_64.c~cfi_backtrace_minor_fixes 2006-11-15 18:35:50.519688064 +0530 > > +++ crash-4.0-3.9-rachita/unwind_x86_32_64.c 2006-11-15 19:31:45.705622272 +0530 > > @@ -1036,9 +1036,8 @@ dump_local_unwind_tables(void) > > > > > > int > > -dwarf_backtrace(struct bt_info *bt, ulong stacktop) > > +dwarf_backtrace(struct bt_info *bt, int level, ulong stacktop) > > { > > - int n = 0; > > unsigned long bp, offset; > > struct syment *sp; > > char *name; > > @@ -1051,7 +1050,7 @@ dwarf_backtrace(struct bt_info *bt, ulon > > UNW_PC(frame) = bt->instptr; > > > > /* read rbp from stack for non active tasks */ > > - if (!(bt->flags & BT_DUMPFILE_SEARCH) ) { > > + if (!(bt->flags & BT_DUMPFILE_SEARCH) && !bt->bptr) { > > // readmem(frame->regs.rsp, KVADDR, &bp, > > readmem(UNW_SP(frame), KVADDR, &bp, > > sizeof(unsigned long), "reading bp", FAULT_ON_ERROR); > > @@ -1084,7 +1083,7 @@ dwarf_backtrace(struct bt_info *bt, ulon > > > > > > name = sp->name; > > - fprintf(fp, " #0 [%016lx] %s at %016lx \n", UNW_SP(frame), name, UNW_PC(frame)); > > + fprintf(fp, " #%d [%016lx] %s at %016lx \n", level, UNW_SP(frame), name, UNW_PC(frame)); > > > > if (CRASHDEBUG(2)) > > fprintf(fp, " < SP: %lx PC: %lx FP: %lx >\n", UNW_SP(frame), > > @@ -1092,7 +1091,12 @@ dwarf_backtrace(struct bt_info *bt, ulon > > > > while ((UNW_SP(frame) < stacktop) > > && !unwind(frame) && UNW_PC(frame)) { > > - n++; > > + /* To prevent rip pushed on IRQ stack being reported both > > + * both on the IRQ and process stacks > > + */ > > + if ((bt->flags & BT_IRQSTACK) && (UNW_SP(frame) >= stacktop - 16)) > > + break; > > + level++; > > sp = value_search(UNW_PC(frame), &offset); > > if (!sp) { > > if (CRASHDEBUG(1)) > > @@ -1101,9 +1105,24 @@ dwarf_backtrace(struct bt_info *bt, ulon > > UNW_PC(frame)); > > break; > > } > > + > > + /* > > + * If offset is zero, it means we have crossed over to the next > > + * function. Recalculate by adjusting the text address > > + */ > > + if (!offset) { > > + sp = value_search(UNW_PC(frame) - 1, &offset); > > + if (!sp) { > > + if (CRASHDEBUG(1)) > > + fprintf(fp, > > + "unwind: cannot find symbol for PC: %lx\n", > > + UNW_PC(frame)-1); > > + goto bailout; > > + } > > + } > > name = sp->name; > > - fprintf(fp, "%s#%d [%016lx] %s at %016lx \n", n < 10 ? " " : "", > > - n, UNW_SP(frame), name, UNW_PC(frame)); > > + fprintf(fp, "%s#%d [%016lx] %s at %016lx \n", level < 10 ? " " : "", > > + level, UNW_SP(frame), name, UNW_PC(frame)); > > > > if (CRASHDEBUG(2)) > > fprintf(fp, " < SP: %lx PC: %lx FP: %lx >\n", UNW_SP(frame), > > @@ -1112,7 +1131,49 @@ dwarf_backtrace(struct bt_info *bt, ulon > > > > bailout: > > FREEBUF(frame); > > - return TRUE; > > + return ++level; > > +} > > + > > +int dwarf_print_stack_entry(struct bt_info *bt, int level) > > +{ > > + int n = 0; > > + unsigned long offset; > > + struct syment *sp; > > + char *name; > > + struct unwind_frame_info *frame; > > + > > + frame = (struct unwind_frame_info *)GETBUF(sizeof(struct unwind_frame_info)); > > + UNW_SP(frame) = bt->stkptr; > > + UNW_PC(frame) = bt->instptr; > > + > > + sp = value_search(UNW_PC(frame), &offset); > > + if (!sp) { > > + if (CRASHDEBUG(1)) > > + fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", > > + UNW_PC(frame)); > > + goto bailout; > > + } > > + > > + /* > > + * If offset is zero, it means we have crossed over to the next > > + * function. Recalculate by adjusting the text address > > + */ > > + if (!offset) { > > + sp = value_search(UNW_PC(frame) - 1, &offset); > > + if (!sp) { > > + if (CRASHDEBUG(1)) > > + fprintf(fp, > > + "unwind: cannot find symbol for PC: %lx\n", > > + UNW_PC(frame)-1); > > + goto bailout; > > + } > > + } > > + name = sp->name; > > + fprintf(fp, " #%d [%016lx] %s at %016lx \n", level, UNW_SP(frame), name, UNW_PC(frame)); > > + > > +bailout: > > + FREEBUF(frame); > > + return level; > > } > > > > void > > diff -puN defs.h~cfi_backtrace_minor_fixes defs.h > > --- crash-4.0-3.9/defs.h~cfi_backtrace_minor_fixes 2006-11-15 18:51:28.030164808 +0530 > > +++ crash-4.0-3.9-rachita/defs.h 2006-11-15 18:51:46.272391568 +0530 > > @@ -645,6 +645,7 @@ struct bt_info { > > ulonglong flags; > > ulong instptr; > > ulong stkptr; > > + ulong bptr; > > ulong stackbase; > > ulong stacktop; > > char *stackbuf; > > @@ -3626,7 +3627,7 @@ struct machine_specific { > > * unwind_x86_32_64.c > > */ > > void init_unwind_table(void); > > -int dwarf_backtrace(struct bt_info *, ulong); > > +int dwarf_backtrace(struct bt_info *, int, ulong); > > void dwarf_debug(struct bt_info *); > > > > #endif > > _ -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility