Ejemplo n.º 1
0
static void report_and_quit ( const Char* report,
                              UnwindStartRegs* startRegsIN )
{
   Addr stacktop;
   Addr ips[BACKTRACE_DEPTH];
   Int  n_ips;
   ThreadState *tst 
      = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
 
   // If necessary, fake up an ExeContext which is of our actual real CPU
   // state.  Could cause problems if we got the panic/exception within the
   // execontext/stack dump/symtab code.  But it's better than nothing.
   UnwindStartRegs startRegs;
   VG_(memset)(&startRegs, 0, sizeof(startRegs));

   if (startRegsIN == NULL) {
      GET_STARTREGS(&startRegs);
   } else {
      startRegs = *startRegsIN;
   }
 
   stacktop = tst->os_state.valgrind_stack_init_SP;

   n_ips = 
      VG_(get_StackTrace_wrk)(
         0/*tid is unknown*/, 
         ips, BACKTRACE_DEPTH, 
         NULL/*array to dump SP values in*/,
         NULL/*array to dump FP values in*/,
         &startRegs, stacktop
      );
   VG_(clo_xml) = False;
   VG_(pp_StackTrace) (ips, n_ips);
 
   VG_(show_sched_status)();
   VG_(printf)(
      "\n"
      "Note: see also the FAQ in the source distribution.\n"
      "It contains workarounds to several common problems.\n"
      "In particular, if Valgrind aborted or crashed after\n"
      "identifying problems in your program, there's a good chance\n"
      "that fixing those problems will prevent Valgrind aborting or\n"
      "crashing, especially if it happened in m_mallocfree.c.\n"
      "\n"
      "If that doesn't help, please report this bug to: %s\n\n"
      "In the bug report, send all the above text, the valgrind\n"
      "version, and what OS and version you are using.  Thanks.\n\n",
      report);
   VG_(exit)(1);
}
Ejemplo n.º 2
0
// Print the scheduler status.
static void show_sched_status_wrk ( Bool host_stacktrace,
                                    Bool stack_usage,
                                    Bool exited_threads,
                                    const UnwindStartRegs* startRegsIN)
{
   Int i; 
   if (host_stacktrace) {
      const Bool save_clo_xml = VG_(clo_xml);
      Addr stacktop;
      Addr ips[BACKTRACE_DEPTH];
      Int  n_ips;
      ThreadState *tst 
         = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
 
      // If necessary, fake up an ExeContext which is of our actual real CPU
      // state.  Could cause problems if we got the panic/exception within the
      // execontext/stack dump/symtab code.  But it's better than nothing.
      UnwindStartRegs startRegs;
      VG_(memset)(&startRegs, 0, sizeof(startRegs));
      
      if (startRegsIN == NULL) {
         GET_STARTREGS(&startRegs);
      } else {
         startRegs = *startRegsIN;
      }
 
      stacktop = tst->os_state.valgrind_stack_init_SP;

      n_ips = 
         VG_(get_StackTrace_wrk)(
            0/*tid is unknown*/, 
            ips, BACKTRACE_DEPTH, 
            NULL/*array to dump SP values in*/,
            NULL/*array to dump FP values in*/,
            &startRegs, stacktop
         );
      VG_(printf)("\nhost stacktrace:\n"); 
      VG_(clo_xml) = False;
      VG_(pp_StackTrace) (ips, n_ips);
      VG_(clo_xml) = save_clo_xml;
   }

   VG_(printf)("\nsched status:\n"); 
   VG_(printf)("  running_tid=%d\n", VG_(get_running_tid)());
   for (i = 1; i < VG_N_THREADS; i++) {
      VgStack* stack 
         = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
      /* If a thread slot was never used (yet), valgrind_stack_base is 0.
         If a thread slot is used by a thread or was used by a thread which
         has exited, then valgrind_stack_base points to the stack base. */
      if (VG_(threads)[i].status == VgTs_Empty
          && (!exited_threads || stack == 0)) continue;
      VG_(printf)("\nThread %d: status = %s\n", i, 
                  VG_(name_of_ThreadStatus)(VG_(threads)[i].status) );
      if (VG_(threads)[i].status != VgTs_Empty)
         VG_(get_and_pp_StackTrace)( i, BACKTRACE_DEPTH );
      if (stack_usage && VG_(threads)[i].client_stack_highest_byte != 0 ) {
         Addr start, end;
         
         start = end = 0;
         VG_(stack_limits)(VG_(threads)[i].client_stack_highest_byte,
                           &start, &end);
         if (start != end)
            VG_(printf)("client stack range: [%p %p] client SP: %p\n",
                        (void*)start, (void*)end, (void*)VG_(get_SP)(i));
         else
            VG_(printf)("client stack range: ???????\n");
      }
      if (stack_usage && stack != 0)
          VG_(printf)("valgrind stack top usage: %ld of %ld\n",
                      VG_STACK_ACTIVE_SZB 
                      - VG_(am_get_VgStack_unused_szB)(stack,
                                                       VG_STACK_ACTIVE_SZB),
                      (SizeT) VG_STACK_ACTIVE_SZB);
   }
   VG_(printf)("\n");
}
Ejemplo n.º 3
0
// Print the scheduler status.
static void show_sched_status_wrk ( Bool host_stacktrace,
                                    Bool stack_usage,
                                    Bool exited_threads,
                                    const UnwindStartRegs* startRegsIN)
{
   Int i; 
   if (host_stacktrace) {
      const Bool save_clo_xml = VG_(clo_xml);
      Addr stacktop;
      Addr ips[BACKTRACE_DEPTH];
      Int  n_ips;
      ThreadState *tst 
         = VG_(get_ThreadState)( VG_(lwpid_to_vgtid)( VG_(gettid)() ) );
 
      // If necessary, fake up an ExeContext which is of our actual real CPU
      // state.  Could cause problems if we got the panic/exception within the
      // execontext/stack dump/symtab code.  But it's better than nothing.
      UnwindStartRegs startRegs;
      VG_(memset)(&startRegs, 0, sizeof(startRegs));
      
      if (startRegsIN == NULL) {
         GET_STARTREGS(&startRegs);
      } else {
         startRegs = *startRegsIN;
      }
 
      stacktop = tst->os_state.valgrind_stack_init_SP;

      n_ips = 
         VG_(get_StackTrace_wrk)(
            0/*tid is unknown*/, 
            ips, BACKTRACE_DEPTH, 
            NULL/*array to dump SP values in*/,
            NULL/*array to dump FP values in*/,
            &startRegs, stacktop
         );
      VG_(printf)("\nhost stacktrace:\n"); 
      VG_(clo_xml) = False;
      VG_(pp_StackTrace) (ips, n_ips);
      VG_(clo_xml) = save_clo_xml;
   }

   VG_(printf)("\nsched status:\n"); 
   if (VG_(threads) == NULL) {
      VG_(printf)("  scheduler not yet initialised\n");
   } else {
      VG_(printf)("  running_tid=%u\n", VG_(get_running_tid)());
      for (i = 1; i < VG_N_THREADS; i++) {
         VgStack *stack 
            = (VgStack*)VG_(threads)[i].os_state.valgrind_stack_base;
         /* If a thread slot was never used (yet), valgrind_stack_base is 0.
            If a thread slot is used by a thread or was used by a thread which
            has exited, then valgrind_stack_base points to the stack base. */
         if (VG_(threads)[i].status == VgTs_Empty
             && (!exited_threads || stack == 0)) continue;
         print_thread_state(stack_usage, "", i);
         if (VG_(inner_threads) != NULL) {
            /* An inner V has informed us (the outer) of its thread array.
               Report the inner guest stack trace. */
            UInt inner_tid;

            for (inner_tid = 1; inner_tid < VG_N_THREADS; inner_tid++) {
               if (VG_(threads)[i].os_state.lwpid 
                   == VG_(inner_threads)[inner_tid].os_state.lwpid) {
                  ThreadState* save_outer_vg_threads = VG_(threads);

                  VG_(threads) = VG_(inner_threads);
                  print_thread_state(stack_usage, "INNER ", inner_tid);
                  VG_(threads) = save_outer_vg_threads;
                  break;
               }
            }
         }
      }
   }
   VG_(printf)("\n");
}