Segfault in re_search_internal() - [Was: Segfault in re_string_reconstruct()]

Jeremy Bowen jeremy.bowen at pertronic.co.nz
Thu Nov 6 03:32:55 UTC 2008


On Thursday 06 November 2008 10:33:37 am Jeremy Bowen wrote:

> OK so now I'm playing whack-a-mole with this :-)

Right I've reconfigured uClibc to use the "old" regex code and have triggered 
my problem again. I'm using "mdev" from busybox 1.12.0 to generate the 
problem.

I have some disassembly of the working and segfaulting code.

This is triggered within the PATFETCH macro in libc/misc/regex/regex_old.c 
around line #1977. NOTE: I have expanded the macro with additional linefeeds 
to aid tracing of the issue.

...
#  else /* BYTE */
#   define PATFETCH(c)							\
  do {                                              \
      if (p == pend)                                \
          return REG_EEND;                          \
    c = (unsigned char) *p++;						\
    if (translate)                                  \
    {                                               \
+       dprintf(2, ".");                                           \
        c = (unsigned char) translate[c];                          \
    }                                                              \
  } while (0)
#  endif /* WCHAR */
# endif
...

With the addition of the dprinf() call, the code works.
Removing the dprintf() and it segfaults.

This macro is included at about line #2550 of regex_old.c and I have wrapped 
__asm__ delimiters around the problematic section.
...
    /* Loop through the uncompiled pattern until we're at the end.  */
    while (p != pend)
    {
        __asm__("# AA");
        PATFETCH (c);
        __asm__("# FF");
...

Disassembly from avr32-linux-objdump (and listing from gcc -S) follows

First the standard (segfaulting) version.
===========================================================================
.L143:
        mov     r8, 32
        st.w    r3[4], r8
.L138:
        ld.w    r4, r3[0]
        mov     r1, 0
        mov     r11, 32
        mov     r2, r1
        mov     r0, r1
        stdsp   sp[64], r4
        stdsp   sp[68], r1
        stdsp   sp[108], r1
        stdsp   sp[112], r11
        bral    .L1114
.L147:
#APP
        # AA
#NO_APP
        mov     r10, r9
        ld.ub   r7, r10++
        lddsp   r8, sp[60]
        stdsp   sp[264], r10
        cp.w    r8, 0
        breq    .L148

        ld.ub   r7, r8[r7]
.L148:
#APP
        # FF
#NO_APP
...
-----objdump---------------------------------------------------------------
     526:       32 0b           mov     r11,32
     528:       02 92           mov     r2,r1
     52a:       02 90           mov     r0,r1
     52c:       51 04           stdsp   sp[0x40],r4
     52e:       51 11           stdsp   sp[0x44],r1
     530:       51 b1           stdsp   sp[0x6c],r1
     532:       51 cb           stdsp   sp[0x70],r11
     534:       e0 8f 00 00     bral    534 <byte_regex_compile+0xf8>
     538:       12 9a           mov     r10,r9
     53a:       15 37           ld.ub   r7,r10++
     53c:       40 f8           lddsp   r8,sp[0x3c]
     53e:       54 2a           stdsp   sp[0x108],r10
     540:       58 08           cp.w    r8,0
     542:       c0 00           breq    542 <byte_regex_compile+0x106>
     544:       f0 07 07 07     ld.ub   r7,r8[r7]


===========================================================================
And now the working non-segfaulting version with the call to dprintf()

.L143:
        mov     r8, 32
        st.w    r3[4], r8
.L138:
        ld.w    r4, r3[0]
        mov     r1, 0
        mov     r9, 32
        mov     r2, r1
        stdsp   sp[60], r4
        stdsp   sp[64], r1
        stdsp   sp[68], r1
        stdsp   sp[100], r1
        stdsp   sp[104], r9
        bral    .L1129
.L147:
#APP
        # AA
#NO_APP
        ld.ub   r7, r8++
        stdsp   sp[256], r8
        lddsp   r8, sp[56]
        cp.w    r8, 0
        breq    .L148

        lda.w   r11, .LC9
        mov     r12, 2
        call    dprintf
        lddsp   lr, sp[56]

        ld.ub   r7, lr[r7]
.L148:
#APP
        # FF
#NO_APP

-----objdump---------------------------------------------------------------
     52a:       32 09           mov     r9,32
     52c:       02 92           mov     r2,r1
     52e:       50 f4           stdsp   sp[0x3c],r4
     530:       51 01           stdsp   sp[0x40],r1
     532:       51 11           stdsp   sp[0x44],r1
     534:       51 91           stdsp   sp[0x64],r1
     536:       51 a9           stdsp   sp[0x68],r9
     538:       e0 8f 00 00     bral    538 <byte_regex_compile+0xf8>
     53c:       11 37           ld.ub   r7,r8++
     53e:       54 08           stdsp   sp[0x100],r8
     540:       40 e8           lddsp   r8,sp[0x38]
     542:       58 08           cp.w    r8,0
     544:       c0 00           breq    544 <byte_regex_compile+0x104>
     546:       e0 6b 00 00     mov     r11,0
     54a:       ec 0b 03 2b     ld.w    r11,r6[r11<<0x2]
     54e:       30 2c           mov     r12,2
     550:       e0 6e 00 00     mov     lr,0
     554:       ec 0e 03 2e     ld.w    lr,r6[lr<<0x2]
     558:       5d 1e           icall   lr
     55a:       40 ee           lddsp   lr,sp[0x38]
     55c:       fc 07 07 07     ld.ub   r7,lr[r7]

===========================================================================

I think this is compiled with -Os which is standard for uClibc.

I don't know enough about the AVR32 instruction set to spot the problem but 
again, it feels like a compiler bug to me.

-- 
Cheers
JeremyB



More information about the uClibc mailing list