------- Comment #3 from dave at hiauly1 dot hia dot nrc dot ca 2006-01-01 17:11 ------- Subject: Re: FAIL: a85013b: *** glibc detected *** free(): invalid pointer: 0x00062a00 ***
I've looked at the failure of a85013b.adb. The problem seems to be that "new" is applying a kind of rounding to the pointer returned by malloc. Then, the rounded pointer is used for the call to free. This is the cause of the invalid pointer error and the test being aborted by free(). The rounding occurs in this function: -------------- -- New_ATCB -- -------------- function New_ATCB (Entry_Num : Task_Entry_Index) return Task_Id is begin return new Ada_Task_Control_Block (Entry_Num); end New_ATCB This is the assembly code (-O0): (gdb) disass Dump of assembler code for function system.task_primitives.operations.new_atcb: 0x0003186c <system.task_primitives.operations.new_atcb+0>: stw rp,-14(,sp) 0x00031870 <system.task_primitives.operations.new_atcb+4>: copy r3,r1 0x00031874 <system.task_primitives.operations.new_atcb+8>: copy sp,r3 0x00031878 <system.task_primitives.operations.new_atcb+12>: stw,ma r1,40(,sp) 0x0003187c <system.task_primitives.operations.new_atcb+16>: stw r4,8(,r3) 0x00031880 <system.task_primitives.operations.new_atcb+20>: stw r26,-24(,r3) 0x00031884 <system.task_primitives.operations.new_atcb+24>: ldw -24(,r3),ret0 0x00031888 <system.task_primitives.operations.new_atcb+28>: cmpiclr,< 0,ret0,r0 0x0003188c <system.task_primitives.operations.new_atcb+32>: ldi 0,ret0 0x00031890 <system.task_primitives.operations.new_atcb+36>: depw,z ret0,28,29,ret0 0x00031894 <system.task_primitives.operations.new_atcb+40>: ldo 757(ret0),ret0 0x00031898 <system.task_primitives.operations.new_atcb+44>: depwi 0,31,4,ret0 0x0003189c <system.task_primitives.operations.new_atcb+48>: ldo 10(ret0),ret0 0x000318a0 <system.task_primitives.operations.new_atcb+52>: copy ret0,r26 ---Type <return> to continue, or q <return> to quit--- 0x000318a4 <system.task_primitives.operations.new_atcb+56>: b,l 0x2e438 <__gnat_malloc>,rp 0x000318a8 <system.task_primitives.operations.new_atcb+60>: nop 0x000318ac <system.task_primitives.operations.new_atcb+64>: copy ret0,r20 0x000318b0 <system.task_primitives.operations.new_atcb+68>: copy r20,ret0 0x000318b4 <system.task_primitives.operations.new_atcb+72>: sub r0,ret0,ret0 0x000318b8 <system.task_primitives.operations.new_atcb+76>: extrw,u ret0,31,4,r19 0x000318bc <system.task_primitives.operations.new_atcb+80>: copy r20,ret0 0x000318c0 <system.task_primitives.operations.new_atcb+84>: add,l ret0,r19,ret0 0x000318c4 <system.task_primitives.operations.new_atcb+88>: copy ret0,r4 0x000318c8 <system.task_primitives.operations.new_atcb+92>: copy r4,ret0 0x000318cc <system.task_primitives.operations.new_atcb+96>: copy ret0,r26 0x000318d0 <system.task_primitives.operations.new_atcb+100>: ldw -24(,r3),r25 0x000318d4 <system.task_primitives.operations.new_atcb+104>: b,l 0x32698 <system__tasking__ada_task_control_blockIP>,rp 0x000318d8 <system.task_primitives.operations.new_atcb+108>: nop 0x000318dc <system.task_primitives.operations.new_atcb+112>: copy r4,ret0 0x000318e0 <system.task_primitives.operations.new_atcb+116>: ldw -14(,r3),rp 0x000318e4 <system.task_primitives.operations.new_atcb+120>: ldw 8(,r3),r4 ---Type <return> to continue, or q <return> to quit--- 0x000318e8 <system.task_primitives.operations.new_atcb+124>: ldo 40(r3),sp 0x000318ec <system.task_primitives.operations.new_atcb+128>: ldw,mb -40(,sp),r3 0x000318f0 <system.task_primitives.operations.new_atcb+132>: bv,n r0(rp) End of assembler dump(gdb) bt #0 0x000318cc in system.task_primitives.operations.new_atcb (entry_num=1) at s-taprop.adb:752 #1 0x000512f8 in system.tasking.stages.create_task (priority=-1, size=-2147483648, task_info=default_scope, num_entries=1, master=4, state=0xc068c746, discriminants=3228092176, elaborated=0xc068c714, chain=, task_image=0x5edf4, created_task=0x0) at s-tassta.adb:574 #2 0x00055498 in a85013b__tTKVIP___789 () at a85013b.adb:65 #3 0x000551c8 in a85013b () at a85013b.adb:65 #4 0x00014d84 in main () (gdb) p $r19 $8 = 8 (gdb) p $r20 $9 = 562904 (gdb) p $ret0 $10 = 562912 The value in r20 is the result that was returned in ret0 in the call to __gnat_malloc. The value in $ret0 at this point is the value that system.task_primitives.operations.new_atcb returns and is subsequently used in the call to free(). I don't know ada well enough to know where this bit of code comes from 0x000318b0 <system.task_primitives.operations.new_atcb+68>: copy r20,ret0 0x000318b4 <system.task_primitives.operations.new_atcb+72>: sub r0,ret0,ret0 0x000318b8 <system.task_primitives.operations.new_atcb+76>: extrw,u ret0,31,4,r19 0x000318bc <system.task_primitives.operations.new_atcb+80>: copy r20,ret0 0x000318c0 <system.task_primitives.operations.new_atcb+84>: add,l ret0,r19,ret0 but it appears to round the address returned by malloc up to a 16-byte boundary. The rounded address is used in the call to free. This is undefined: free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Other- wise, or if free(ptr) has already been called before, undefined behaviour occurs. It seems that the 16-byte alignment used for TCBs is a result of using 16-byte alignment for atomic_lock_t. Changing the alignment to 8 fixes the testsuite failures. The current glibc implementation handles lock objects that aren't aligned to 16-byte boundaries by dynamically picking an aligned lock word: /* We need 128-bit alignment for the ldcw semaphore. At most, we are assured of 64-bit alignment for stack locals and malloc'd data. Thus, we use a struct with four ints for the atomic lock type. The locking code will figure out which of the four to use for the ldcw semaphore. */ typedef volatile struct { int lock[4]; } __attribute__ ((aligned(16))) __atomic_lock_t; It's unclear to me whether changing the alignment for atomic_lock_t in s-osinte-linux-hppa.ads is correct as it changes struct layouts, and could cause problems if an object containing an atomic_lock_t object is copied. It is clear that the pointer returned by malloc must be retained for the free operation. Dave -- J. David Anglin [EMAIL PROTECTED] National Research Council of Canada (613) 990-0752 (FAX: 952-6602) -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24533