debugallocation: fix bus error on mipsel-linux platform when enable use_malloc_page_fence

Fix below "BUS ERROR" issue:

a0 hold start address of memory block allocated by DebugAllocate in debugallocation.cc

gdb) info registers
          zero       at       v0       v1       a0       a1       a2       a3
 R0   00000000 10008700 772f62a0 00084d40 766dcfef 7fb5f420 00000000 004b4dd8
            t0       t1       t2       t3       t4       t5       t6       t7
 R8   7713c1a0 7712dbc0 ffffffff 777bc000 f0000000 00000001 00000000 00403d10
            s0       s1       s2       s3       s4       s5       s6       s7
 R16  7fb5ff1c 00401b9c 77050020 7fb5fb18 00000000 004cb008 004ca748 ffffffff
            t8       t9       k0       k1       gp       sp       s8       ra
 R24  0000002f 771adcd4 00000000 00000000 771f4140 7fb5f408 7fb5f430 771add6c
            sr       lo       hi      bad    cause       pc
      00008713 0000e9fe 00000334 766dcff7 00800010 771adcfc
           fsr      fir
      00000004 00000000

(gdb) disassemble
Dump of assembler code for function _ZNSs4_Rep10_M_disposeERKSaIcE:
   0x771adcd4 <+0>:     lui     gp,0x4
   0x771adcd8 <+4>:     addiu   gp,gp,25708
   0x771adcdc <+8>:     addu    gp,gp,t9
   0x771adce0 <+12>:    lw      v0,-28696(gp)
   0x771adce4 <+16>:    beq     a0,v0,0x771add38 <_ZNSs4_Rep10_M_disposeERKSaIcE+100>
   0x771adce8 <+20>:    nop
   0x771adcec <+24>:    lw      v0,-30356(gp)
   0x771adcf0 <+28>:    beqzl   v0,0x771add1c <_ZNSs4_Rep10_M_disposeERKSaIcE+72>
   0x771adcf4 <+32>:    lw      v0,8(a0)
   0x771adcf8 <+36>:    sync
=> 0x771adcfc <+40>:    ll      v0,8(a0)
   0x771add00 <+44>:    addiu   at,v0,-1
   0x771add04 <+48>:    sc      at,8(a0)
   0x771add08 <+52>:    beqz    at,0x771adcfc <_ZNSs4_Rep10_M_disposeERKSaIcE+40>
   0x771add0c <+56>:    nop
   0x771add10 <+60>:    sync
   0x771add14 <+64>:    b       0x771add24 <_ZNSs4_Rep10_M_disposeERKSaIcE+80>
   0x771add18 <+68>:    nop
   0x771add1c <+72>:    addiu   v1,v0,-1
   0x771add20 <+76>:    sw      v1,8(a0)
   0x771add24 <+80>:    bgtz    v0,0x771add38 <_ZNSs4_Rep10_M_disposeERKSaIcE+100>
   0x771add28 <+84>:    nop
   0x771add2c <+88>:    lw      t9,-27072(gp)
   0x771add30 <+92>:    jr      t9
   0x771add34 <+96>:    nop
   0x771add38 <+100>:   jr      ra
   0x771add3c <+104>:   nop
End of assembler dump.

ll instruction manual:
Load Linked:
Loads the destination register with the contents of the word
that is at the memory location. This instruction implicity performs
a SYNC operation; all loads and stores to shared memory fetched prior
to the ll must access memory before the ll, and loads and stores to
shared memory fetched subsequent to the ll must access memory after ll.
Load Linked and Store Conditional can be use to automatically update
memory locations. *This instruction is not valid in the mips1 architectures.
The machine signals an address exception when the effective address is not
divisible by four.

Signed-off-by: Wang YanQing <udknight@gmail.com>
Signed-off-by: Aliaksey Kandratsenka <alk@tut.by>
[alk@tut.by: removed addition of unused #include]
This commit is contained in:
Wang YanQing 2014-02-11 23:20:31 +08:00 committed by Aliaksey Kandratsenka
parent 38bfc7a1c2
commit a0ed9ace53
1 changed files with 16 additions and 7 deletions

View File

@ -141,6 +141,12 @@ extern "C" int pthread_once(pthread_once_t *, void (*)(void))
static void TracePrintf(int fd, const char *fmt, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
// Round "value" up to next "alignment" boundary.
// Requires that "alignment" be a power of two.
static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
// The do_* functions are defined in tcmalloc/tcmalloc.cc,
// which is included before this file
// when TCMALLOC_FOR_DEBUGALLOCATION is defined
@ -349,8 +355,17 @@ class MallocBlock {
static size_t real_malloced_size(size_t size) {
return size + sizeof(MallocBlock);
}
/*
* Here we assume size of page is kMinAlign aligned,
* so if size is MALLOC_ALIGNMENT aligned too, then we could
* guarantee return address is also kMinAlign aligned, because
* mmap return address at nearby page boundary on Linux.
*/
static size_t real_mmapped_size(size_t size) {
return size + MallocBlock::data_offset();
size_t tmp = size + MallocBlock::data_offset();
tmp = RoundUp(tmp, kMinAlign);
return tmp;
}
size_t real_size() {
@ -1275,12 +1290,6 @@ extern "C" PERFTOOLS_DLL_DECL void tc_deletearray_nothrow(void* p, const std::no
DebugDeallocate(p, MallocBlock::kArrayNewType);
}
// Round "value" up to next "alignment" boundary.
// Requires that "alignment" be a power of two.
static intptr_t RoundUp(intptr_t value, intptr_t alignment) {
return (value + alignment - 1) & ~(alignment - 1);
}
// This is mostly the same as do_memalign in tcmalloc.cc.
static void *do_debug_memalign(size_t alignment, size_t size) {
// Allocate >= size bytes aligned on "alignment" boundary