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.
