예제 #1
0
/*inline*/ Bool Seg__is_freed(Seg* seg)
{
   if (!is_known_segment(seg))
      return False;
   else
      return seg->nextfree != (Seg*)1;
}
예제 #2
0
void pc_pp_Error ( Error* err )
{
   const Bool xml = VG_(clo_xml); /* a shorthand, that's all */

   XError *xe = (XError*)VG_(get_error_extra)(err);
   tl_assert(xe);

   switch (VG_(get_error_kind)(err)) {

   //----------------------------------------------------------
   case XE_SorG:

      if (xml) {

         emit( "  <kind>SorG</kind>\n");
         emit( "  <what>Invalid %s of size %ld</what>\n",
               xe->XE.SorG.sszB < 0 ? "write" : "read",
               Word__abs(xe->XE.SorG.sszB) );
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
         emit( "  <auxwhat>Address %#lx expected vs actual:</auxwhat>\n",
               xe->XE.SorG.addr );
         emiN( "  <auxwhat>Expected: %t</auxwhat>\n",
               &xe->XE.SorG.expect[0] );
         emiN( "  <auxwhat>Actual:   %t</auxwhat>\n", 
               &xe->XE.SorG.actual[0] );

      } else {

         emit( "Invalid %s of size %ld\n", 
               xe->XE.SorG.sszB < 0 ? "write" : "read",
               Word__abs(xe->XE.SorG.sszB) );
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
         emit( " Address %#lx expected vs actual:\n", xe->XE.SorG.addr );
         emit( " Expected: %s\n", &xe->XE.SorG.expect[0] );
         emit( " Actual:   %s\n", &xe->XE.SorG.actual[0] );

      }
      break;

   //----------------------------------------------------------
   case XE_Heap: {
      Char *place, *legit, *how_invalid;
      Addr a    = xe->XE.Heap.addr;
      Seg* vseg = xe->XE.Heap.vseg;

      tl_assert(is_known_segment(vseg) || NONPTR == vseg);

      if (NONPTR == vseg) {
         // Access via a non-pointer

         if (xml) {

            emit( "  <kind>Heap</kind>\n");
            emit( "  <what>Invalid %s of size %ld</what>\n",
                  readwrite(xe->XE.Heap.sszB),
                  Word__abs(xe->XE.Heap.sszB) );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( "  <auxwhat>Address %#lx is not derived from "
                  "any known block</auxwhat>\n", a );

         } else {

            emit( "Invalid %s of size %ld\n",
                  readwrite(xe->XE.Heap.sszB),
                  Word__abs(xe->XE.Heap.sszB) );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( " Address %#lx is not derived from "
                  "any known block\n", a );

         }

      } else {
         // Access via a pointer, but outside its range.
         Int cmp;
         UWord miss_size;
         Seg__cmp(vseg, a, &cmp, &miss_size);
         if      (cmp  < 0) place = "before";
         else if (cmp == 0) place = "inside";
         else               place = "after";
         how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp )
                       ? "Doubly-invalid" : "Invalid" );
         legit = ( Seg__is_freed(vseg) ? "once-" : "" );

         if (xml) {

            emit( "  <kind>Heap</kind>\n");
            emit( "  <what>%s %s of size %ld</what>\n",
                  how_invalid,
                  readwrite(xe->XE.Heap.sszB),
                  Word__abs(xe->XE.Heap.sszB) );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( "  <auxwhat>Address %#lx is %lu bytes %s "
                     "the accessing pointer's</auxwhat>\n",
                  a, miss_size, place );
            emit( "  <auxwhat>%slegitimate range, "
                     "a block of size %lu %s</auxwhat>\n",
                  legit, Seg__size(vseg),
                  Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
            VG_(pp_ExeContext)(Seg__where(vseg));

         } else {

            emit( "%s %s of size %ld\n",
                  how_invalid,
                  readwrite(xe->XE.Heap.sszB),
                  Word__abs(xe->XE.Heap.sszB) );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( " Address %#lx is %lu bytes %s the accessing pointer's\n",
                  a, miss_size, place );
            emit( " %slegitimate range, a block of size %lu %s\n",
                  legit, Seg__size(vseg),
                  Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
            VG_(pp_ExeContext)(Seg__where(vseg));

         }
      }

      /* If we have a better description of the address, show it.
         Note that in XML mode, it will already by nicely wrapped up
         in tags, either <auxwhat> or <xauxwhat>, so we can just emit
         it verbatim. */
      if (xml) {

         if (xe->XE.Heap.descr1)
            emiN( "  %t\n",
                  (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
         if (xe->XE.Heap.descr2)
            emiN( "  %t\n",
                  (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) );
         if (xe->XE.Heap.datasym[0] != 0)
            emiN( "  <auxwhat>Address 0x%llx is %llu bytes "
                  "inside data symbol \"%t\"</auxwhat>\n",
                  (ULong)xe->XE.Heap.addr,
                  (ULong)xe->XE.Heap.datasymoff,
                  xe->XE.Heap.datasym );

      } else {

         if (xe->XE.Heap.descr1)
            emit( " %s\n",
                  (HChar*)VG_(indexXA)( xe->XE.Heap.descr1, 0 ) );
         if (xe->XE.Heap.descr2)
            emit( " %s\n",
                  (HChar*)VG_(indexXA)( xe->XE.Heap.descr2, 0 ) ); 
         if (xe->XE.Heap.datasym[0] != 0)
            emit( " Address 0x%llx is %llu bytes "
                  "inside data symbol \"%s\"\n",
                  (ULong)xe->XE.Heap.addr,
                  (ULong)xe->XE.Heap.datasymoff,
                  xe->XE.Heap.datasym );

      }
      break;
   }

   //----------------------------------------------------------
   case XE_Arith: {
      Seg*   seg1   = xe->XE.Arith.seg1;
      Seg*   seg2   = xe->XE.Arith.seg2;
      Char*  which;

      tl_assert(BOTTOM != seg1);
      tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);

      if (xml) {

         emit( "  <kind>Arith</kind>\n");
         emit( "  <what>Invalid arguments to %s</what>\n",
               xe->XE.Arith.opname );
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
         if (seg1 != seg2) {
            if (NONPTR == seg1) {
               emit( "  <auxwhat>First arg not a pointer</auxwhat>\n" );
            } else if (UNKNOWN == seg1) {
               emit( "  <auxwhat>First arg may be a pointer</auxwhat>\n" );
            } else {
               emit( "  <auxwhat>First arg derived from address %#lx of "
                     "%lu-byte block alloc'd</auxwhat>\n",
                     Seg__addr(seg1), Seg__size(seg1) );
               VG_(pp_ExeContext)(Seg__where(seg1));
            }
            which = "Second arg";
         } else {
            which = "Both args";
         }
         if (NONPTR == seg2) {
            emit( "  <auxwhat>%s not a pointer</auxwhat>\n", which );
         } else {
            emit( "  <auxwhat>%s derived from address %#lx of "
                  "%lu-byte block alloc'd</auxwhat>\n",
                  which, Seg__addr(seg2), Seg__size(seg2) );
            VG_(pp_ExeContext)(Seg__where(seg2));
         }

      } else {

         emit( "Invalid arguments to %s\n",
               xe->XE.Arith.opname );
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
         if (seg1 != seg2) {
            if (NONPTR == seg1) {
               emit( " First arg not a pointer\n" );
            } else if (UNKNOWN == seg1) {
               emit( " First arg may be a pointer\n" );
            } else {
               emit( " First arg derived from address %#lx of "
                     "%lu-byte block alloc'd\n",
                     Seg__addr(seg1), Seg__size(seg1) );
               VG_(pp_ExeContext)(Seg__where(seg1));
            }
            which = "Second arg";
         } else {
            which = "Both args";
         }
         if (NONPTR == seg2) {
            emit( " %s not a pointer\n", which );
         } else {
            emit( " %s derived from address %#lx of "
                  "%lu-byte block alloc'd\n",
                  which, Seg__addr(seg2), Seg__size(seg2) );
            VG_(pp_ExeContext)(Seg__where(seg2));
         }

      }

      break;
   }

   //----------------------------------------------------------
   case XE_SysParam: {
      Addr  lo    = xe->XE.SysParam.lo;
      Addr  hi    = xe->XE.SysParam.hi;
      Seg*  seglo = xe->XE.SysParam.seglo;
      Seg*  seghi = xe->XE.SysParam.seghi;
      Char* s     = VG_(get_error_string) (err);
      Char* what;

      tl_assert(BOTTOM != seglo && BOTTOM != seghi);

      if      (Vg_CoreSysCall == xe->XE.SysParam.part) 
                 what = "Syscall param ";
      else    VG_(tool_panic)("bad CorePart");

      if (seglo == seghi) {
         // freed block
         tl_assert(is_known_segment(seglo));
         tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled?

         if (xml) {

            emit( "  <kind>SysParam</kind>\n");
            emit( "  <what>%s%s contains unaddressable byte(s)</what>\n",
                  what, s );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( "  <auxwhat>Address %#lx is %ld bytes inside a "
                  "%ld-byte block free'd</auxwhat>\n",
                  lo, lo-Seg__addr(seglo), Seg__size(seglo) );
            VG_(pp_ExeContext)(Seg__where(seglo));

         } else {

            emit( " %s%s contains unaddressable byte(s)\n",
                  what, s );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            emit( " Address %#lx is %ld bytes inside a "
                  "%ld-byte block free'd\n",
                  lo, lo-Seg__addr(seglo), Seg__size(seglo) );
            VG_(pp_ExeContext)(Seg__where(seglo));

         }

      } else {
         // mismatch

         if (xml) {

            emit( "  <kind>SysParam</kind>\n");
            emit( "  <what>%s%s is non-contiguous</what>\n",
                  what, s );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            if (UNKNOWN == seglo) {
               emit( "  <auxwhat>First byte is "
                        "not inside a known block</auxwhat>\n" );
            } else {
               emit( "  <auxwhat>First byte (%#lx) is %ld bytes inside a "
                     "%ld-byte block alloc'd</auxwhat>\n",
                     lo, lo-Seg__addr(seglo), Seg__size(seglo) );
               VG_(pp_ExeContext)(Seg__where(seglo));
            }
   
            if (UNKNOWN == seghi) {
               emit( "  <auxwhat>Last byte is "
                        "not inside a known block</auxwhat>\n" );
            } else {
               emit( "  <auxwhat>Last byte (%#lx) is %ld bytes inside a "
                     "%ld-byte block alloc'd</auxwhat>\n",
                     hi, hi-Seg__addr(seghi), Seg__size(seghi) );
               VG_(pp_ExeContext)(Seg__where(seghi));
            }

         } else {

            emit( "%s%s is non-contiguous\n",
                  what, s );
            VG_(pp_ExeContext)( VG_(get_error_where)(err) );
   
            if (UNKNOWN == seglo) {
               emit( " First byte is not inside a known block\n" );
            } else {
               emit( " First byte (%#lx) is %ld bytes inside a "
                     "%ld-byte block alloc'd\n",
                     lo, lo-Seg__addr(seglo), Seg__size(seglo) );
               VG_(pp_ExeContext)(Seg__where(seglo));
            }
   
            if (UNKNOWN == seghi) {
               emit( " Last byte is not inside a known block\n" );
            } else {
               emit( " Last byte (%#lx) is %ld bytes inside a "
                     "%ld-byte block alloc'd\n",
                     hi, hi-Seg__addr(seghi), Seg__size(seghi) );
               VG_(pp_ExeContext)(Seg__where(seghi));
            }

         }

      }
      break;
   }

   default:
      VG_(tool_panic)("pp_Error: unrecognised error kind");
   }
}
예제 #3
0
Addr Seg__addr(Seg* seg)
{
   tl_assert(is_known_segment(seg));
   return seg->addr;
}
예제 #4
0
SizeT Seg__size(Seg* seg)
{
   tl_assert(is_known_segment(seg));
   return seg->szB;
}
예제 #5
0
ExeContext* Seg__where(Seg* seg)
{
   tl_assert(is_known_segment(seg));
   return seg->ec;
}
예제 #6
0
void pc_pp_Error ( Error* err )
{
   XError *xe = (XError*)VG_(get_error_extra)(err);
   tl_assert(xe);

   switch (VG_(get_error_kind)(err)) {

   //----------------------------------------------------------
   case XE_SorG:
      tl_assert(xe);
      VG_(message)(Vg_UserMsg, "Invalid %s of size %ld", 
                               xe->XE.SorG.sszB < 0 ? "write" : "read",
                               Word__abs(xe->XE.SorG.sszB) );
      VG_(pp_ExeContext)( VG_(get_error_where)(err) );
      VG_(message)(Vg_UserMsg, " Address %#lx expected vs actual:",
                               xe->XE.SorG.addr);
      VG_(message)(Vg_UserMsg, " Expected: %s", &xe->XE.SorG.expect[0] );
      VG_(message)(Vg_UserMsg, " Actual:   %s", &xe->XE.SorG.actual[0] );
      break;

   //----------------------------------------------------------
   case XE_Heap: {
      Char *place, *legit, *how_invalid;
      Addr a    = xe->XE.Heap.addr;
      Seg* vseg = xe->XE.Heap.vseg;

      tl_assert(is_known_segment(vseg) || NONPTR == vseg);

      if (NONPTR == vseg) {
         // Access via a non-pointer
         VG_(message)(Vg_UserMsg, "Invalid %s of size %ld",
                                   readwrite(xe->XE.Heap.sszB),
                                   Word__abs(xe->XE.Heap.sszB));
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );
         VG_(message)(Vg_UserMsg,
                      " Address %#lx is not derived from any known block", a);

      } else {
         // Access via a pointer, but outside its range.
         Int cmp;
         UWord miss_size;
         Seg__cmp(vseg, a, &cmp, &miss_size);
         if      (cmp  < 0) place = "before";
         else if (cmp == 0) place = "inside";
         else               place = "after";
         how_invalid = ( ( Seg__is_freed(vseg) && 0 != cmp )
                       ? "Doubly-invalid" : "Invalid" );
         legit = ( Seg__is_freed(vseg) ? "once-" : "" );

         VG_(message)(Vg_UserMsg, "%s %s of size %ld", how_invalid,
                                  readwrite(xe->XE.Heap.sszB),
                                  Word__abs(xe->XE.Heap.sszB));
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );

         VG_(message)(Vg_UserMsg,
                      " Address %#lx is %lu bytes %s the accessing pointer's",
                      a, miss_size, place);
         VG_(message)(Vg_UserMsg,
                      " %slegitimate range, a block of size %lu %s",
                      legit, Seg__size(vseg),
                      Seg__is_freed(vseg) ? "free'd" : "alloc'd" );
         VG_(pp_ExeContext)(Seg__where(vseg));
      }
      if (xe->XE.Heap.descr1[0] != 0)
         VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr1);
      if (xe->XE.Heap.descr2[0] != 0)
         VG_(message)(Vg_UserMsg, " %s", xe->XE.Heap.descr2);
      if (xe->XE.Heap.datasym[0] != 0)
         VG_(message)(Vg_UserMsg, " Address 0x%llx is %llu bytes "
                      "inside data symbol \"%s\"",
                      (ULong)xe->XE.Heap.addr,
                      (ULong)xe->XE.Heap.datasymoff,
                      xe->XE.Heap.datasym);
      break;
   }

   //----------------------------------------------------------
   case XE_Arith: {
      Seg*   seg1   = xe->XE.Arith.seg1;
      Seg*   seg2   = xe->XE.Arith.seg2;
      Char*  which;

      tl_assert(BOTTOM != seg1);
      tl_assert(BOTTOM != seg2 && UNKNOWN != seg2);

      VG_(message)(Vg_UserMsg, "Invalid arguments to %s", xe->XE.Arith.opname);
      VG_(pp_ExeContext)( VG_(get_error_where)(err) );

      if (seg1 != seg2) {
         if (NONPTR == seg1) {
            VG_(message)(Vg_UserMsg, " First arg not a pointer");
         } else if (UNKNOWN == seg1) {
            VG_(message)(Vg_UserMsg, " First arg may be a pointer");
         } else {
            VG_(message)(Vg_UserMsg, " First arg derived from address %#lx of "
                                     "%lu-byte block alloc'd",
                                     Seg__addr(seg1), Seg__size(seg1) );
            VG_(pp_ExeContext)(Seg__where(seg1));
         }
         which = "Second arg";
      } else {
         which = "Both args";
      }
      if (NONPTR == seg2) {
         VG_(message)(Vg_UserMsg, " %s not a pointer", which);
      } else {
         VG_(message)(Vg_UserMsg, " %s derived from address %#lx of "
                                  "%lu-byte block alloc'd",
                      which, Seg__addr(seg2), Seg__size(seg2) );
         VG_(pp_ExeContext)(Seg__where(seg2));
      }
      break;
   }

   //----------------------------------------------------------
   case XE_SysParam: {
      Addr  lo    = xe->XE.SysParam.lo;
      Addr  hi    = xe->XE.SysParam.hi;
      Seg*  seglo = xe->XE.SysParam.seglo;
      Seg*  seghi = xe->XE.SysParam.seghi;
      Char* s     = VG_(get_error_string) (err);
      Char* what;

      tl_assert(BOTTOM != seglo && BOTTOM != seghi);

      if      (Vg_CoreSysCall == xe->XE.SysParam.part) 
                 what = "Syscall param ";
      else    VG_(tool_panic)("bad CorePart");

      if (seglo == seghi) {
         // freed block
         tl_assert(is_known_segment(seglo));
         tl_assert(Seg__is_freed(seglo)); // XXX what if it's now recycled?
         VG_(message)(Vg_UserMsg, "%s%s contains unaddressable byte(s)",
                                  what, s);
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );

         VG_(message)(Vg_UserMsg, " Address %#lx is %ld bytes inside a "
                                  "%ld-byte block free'd",
                                  lo, lo-Seg__addr(seglo),
                                  Seg__size(seglo) );
         VG_(pp_ExeContext)(Seg__where(seglo));

      } else {
         // mismatch
         VG_(message)(Vg_UserMsg, "%s%s is non-contiguous", what, s);
         VG_(pp_ExeContext)( VG_(get_error_where)(err) );

         if (UNKNOWN == seglo) {
            VG_(message)(Vg_UserMsg, " First byte is not inside a known block");
         } else {
            VG_(message)(Vg_UserMsg, " First byte (%#lx) is %ld bytes inside a "
                                     "%ld-byte block alloc'd",
                                     lo, lo-Seg__addr(seglo), 
                                     Seg__size(seglo) );
            VG_(pp_ExeContext)(Seg__where(seglo));
         }

         if (UNKNOWN == seghi) {
            VG_(message)(Vg_UserMsg, " Last byte is not inside a known block");
         } else {
            VG_(message)(Vg_UserMsg, " Last byte (%#lx) is %ld bytes inside a "
                                     "%ld-byte block alloc'd",
                                     hi, hi-Seg__addr(seghi),
                                     Seg__size(seghi) );
            VG_(pp_ExeContext)(Seg__where(seghi));
         }
      }
      break;
   }

   default:
      VG_(tool_panic)("pp_Error: unrecognised error kind");
   }
}