https://bugs.kde.org/show_bug.cgi?id=510200

--- Comment #6 from [email protected] ---
The testcase sets the path argument to 4098 'a' characters.  Those are followed
by null terminator:

>> (gdb) p tcases[0]->pathname
>> $1 = 0x7ffff7fbcffe 'a' <repeats 200 times>...
>> (gdb) set print elements 0
>> (gdb) p tcases[0]->pathname
>> $2 = 0x7ffff7fbcffe 'a' <repeats 4098 times>
>> (gdb) p *tcases[0]->pathname
>> $3 = 97 'a' 
>> (gdb) p *(tcases[0]->pathname + 4097)
>> $4 = 97 'a' 
>> (gdb) p *(tcases[0]->pathname + 4098)
>> $5 = 0 '\000'
>> (gdb) p *(tcases[0]->pathname + 4099)
>> $6 = 0 '\000'
>> (gdb) p *(tcases[0]->pathname + 4100)
>> $7 = 0 '\000'
>> (gdb) l
>> 47   {   
>> 48           SAFE_MKNOD("tnode_1", MODE_FIFO_RWX, 0); 
>> 49           SAFE_MKNOD("tnode", MODE_FIFO_RWX, 0); 
>> 50   
>> 51           for (int i = 0; i <= (PATH_MAX + 1); i++)
>> 52                   longpathname[i] = 'a';
>> 53           tcases[0].pathname = longpathname;
>> 54   }   
>> 55   
>> 56   static struct tst_test test = { 
>> (gdb)

The host stacktrace points finger to mc_is_defined_asciiz():

>> host stacktrace:
>> ==2284884==    at 0x580102AB: mc_is_defined_asciiz (mc_main.c:4393)
>> ==2284884==    by 0x580102AB: check_mem_is_defined_asciiz (mc_main.c:4494)
>> ==2284884==    by 0x58099E11: vgPlain_client_syscall (syswrap-main.c:2410)
>> ==2284884==    by 0x58095D7A: handle_syscall (scheduler.c:1214)
>> ==2284884==    by 0x58097C66: vgPlain_scheduler (scheduler.c:1588)
>> ==2284884==    by 0x5810153A: thread_wrapper (syswrap-linux.c:102)
>> ==2284884==    by 0x5810153A: run_a_thread_NORETURN (syswrap-linux.c:154)

 I've added some debugging output to it using  VG_(printf)(...). 

>> /* Check a zero-terminated ascii string.  Tricky -- don't want to
>>    examine the actual bytes, to find the end, until we're sure it is
>>    safe to do so. */
>> 
>> static Bool mc_is_defined_asciiz ( Addr a, Addr* bad_addr, UInt* otag )
>> {
>>    UWord vabits2;
>> 
>>    PROF_EVENT(MCPE_IS_DEFINED_ASCIIZ);
>>    DEBUG("mc_is_defined_asciiz\n");
>> 
>>    if (otag)     *otag = 0; 
>>    if (bad_addr) *bad_addr = 0; 
>>    while (True) {
>>       PROF_EVENT(MCPE_IS_DEFINED_ASCIIZ_LOOP);
>>       vabits2 = get_vabits2(a);
>>       if (VA_BITS2_DEFINED != vabits2) {
>>          // Error!  Nb: Report addressability errors in preference to
>>          // definedness errors.  And don't report definedeness errors unless
>>          // --undef-value-errors=yes.
>>          if (bad_addr) {
>>             *bad_addr = a; 
>>          }    
>>          if (VA_BITS2_NOACCESS == vabits2) {
>>             return MC_AddrErr;
>>          }    
>>          if (MC_(clo_mc_level) >= 2) { 
>>             if (otag && MC_(clo_mc_level) == 3) { 
>>                *otag = MC_(helperc_b_load1)( a ); 
>>             }    
>>             return MC_ValueErr;
>>          }    
>>       }    
>>       /* Ok, a is safe to read. */
>>       if (* ((UChar*)a) == 0) { 
>>          return MC_Ok;
>>       }    
>>       a++; 
>>    }    
>> }

This ^^^ loops over all the 'a' characters, and then it gets to the null
terminator.  At that point * ((UChar*)a) bombs out.  I've added some debug
prints and set a conditional breakpoint.   Valgrind apparently crashes when it
tries to dereference the null terminator.  What confuses me is that I can do
the dereference in gdb without crash.  But when I actually step over that line,
it crashes:

4021:a 4022:a 4023:a 4024:a 4025:a 4026:a 4027:a 4028:a 4029:a 4030:a 4031:a
4032:a 4033:a 4034:a 4035:a 4036:a 4037:a 4038:a 4039:a 4040:a 4041:a 4042:a
4043:a 4044:a 4045:a 4046:a 4047:a 4048:a 4049:a 4050:a 4051:a 4052:a 4053:a
4054:a 4055:a 4056:a 4057:a 4058:a 4059:a 4060:a 4061:a 4062:a 4063:a 4064:a
4065:a 4066:a 4067:a 4068:a 4069:a 4070:a 4071:a 4072:a 4073:a 4074:a 4075:a
4076:a 4077:a 4078:a 4079:a 4080:a 4081:a 4082:a 4083:a 4084:a 4085:a 4086:a
4087:a 4088:a 4089:a 4090:a 4091:a 4092:a 4093:a 4094:a 4095:a 
Breakpoint 1, mc_is_defined_asciiz (a=75886590, bad_addr=<synthetic pointer>,
otag=<synthetic pointer>) at mc_main.c:4415
4415          VG_(printf)("%d:%c ", c, * ((UChar*)a));
(gdb) n
4096:a 4417           c++;
(gdb) n
4393          vabits2 = get_vabits2(a);
(gdb) n
4394          if (VA_BITS2_DEFINED != vabits2) {
(gdb) n
4412          if (* ((UChar*)a) == 0) {
(gdb) n
4415          VG_(printf)("%d:%c ", c, * ((UChar*)a));
(gdb) n
4097:a 4417           c++;
(gdb) n
4393          vabits2 = get_vabits2(a);
(gdb) n
4394          if (VA_BITS2_DEFINED != vabits2) {
(gdb) n
4412          if (* ((UChar*)a) == 0) {
(gdb) p * ((UChar*)a)
$21 = 0 '\000'
(gdb) # now we are just before the crash.  Not sure why gdb can successfully
(gdb) # do the dereference ^^^.  But now when I actually do the step, it will
(gdb) # crash:
(gdb) n
--2367825-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) -
exiting

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to