From: Hyung-Hwan Chung <hyunghwan.chung@gmail.com>
Subject: Re: GNAT Allocation of a very large record
Date: Wed, 14 Aug 2013 18:06:14 -0700 (PDT)
Date: 2013-08-14T18:06:14-07:00 [thread overview]
Message-ID: <0a76f2be-4254-4641-8fa9-844aebacc545@googlegroups.com> (raw)
In-Reply-To: <12ebc074-b545-4528-af28-48864d90d049@googlegroups.com>
On Thursday, August 15, 2013 5:08:32 AM UTC+9, Anh Vo wrote:
> On Wednesday, August 14, 2013 12:32:10 PM UTC-7, Per Sandberg wrote:
>
> > Tried 4 different GCC:s and one failed:
> >
> > gcc 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) x86 ok
> > gcc 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC) x86_64 ok
> > gcc 4.7.3 20130318 for GNAT Pro 7.2.0w (20130317) (GCC) x86_64 ok
> > gcc 4.4.5 (Debian 4.4.5-8) arm (raspberry-pi) fail
>
> It works fine with GNAT-GPL-2013 on Windows and GNATPro 7.1.1 on Red Hat x86.
>
> A. Vo
I tried gcc 4.4.7 20120313 (Red Hat 4.4.7-2) (GCC) x86_64 and it seemed to work find originally. Soon later, I wanted to confirm this at a slightly lower-level and realized that it gave me the illusion that it worked.
It raised the STORAGE_ERROR exception. But the key here is that how it was raised.
Strace reveals that there was a segmentation fault. You can guess that the program catches SIGSEGV from rt_sigaction (SIGSEGV,...) at the beginning.
$ strace ./x1
--<snip>--
rt_sigaction(SIGSEGV, {0x41ac90, [], SA_RESTORER|SA_STACK|SA_RESTART|SA_NODEFER|SA_SIGINFO, 0x7fd6ba93a920}, NULL, 8) = 0
fstat(2, {st_mode=S_IFREG|0664, st_size=2182, ...}) = 0
fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 2), ...}) = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(4, 2), ...}) = 0
brk(0) = 0xd23000
brk(0xd44000) = 0xd44000
write(1, "1. Kind: POINTER_OBJECT Size: 1"..., 34) = 34
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
brk(0xd65000) = 0xd65000
write(1, "2. Allocation Failed\n", 21) = 21
exit_group(0) = ?
Ltrace reveals that the second attempt to 'new' that translated to malloc eventually requested 16 bytes only. You can also print the Pointer_Object_Record'Max_Size_In_Storage_Elements from within the program. I used ltrace to see the real value passed to the malloc function. This comes down to the overflow/wrap-around issue.
$ ltrace ./x1
-- <snip> --
malloc(104) = 0x18cd010
memcpy(0x7fff0c80a6d0, "1. Kind: ", 9) = 0x7fff0c80a6d0
memcpy(0x7fff0c80a6d9, "POINTER_OBJECT", 14) = 0x7fff0c80a6d9
memcpy(0x7fff0c80a6e7, " Size: ", 7) = 0x7fff0c80a6e7
memcpy(0x7fff0c80a6ee, " 10", 3) = 0x7fff0c80a6ee
memcpy(0x6302a8, "1. Kind: POINTER_OBJECT Size: 1"..., 33) = 0x6302a8
memcpy(0x7fff0c80a790, "1. Kind: POINTER_OBJECT Size: 1"..., 33) = 0x7fff0c80a790
fwrite("1. Kind: POINTER_OBJECT Size: 1"..., 34, 1, 0x7f630f8ad780) = 1
malloc(16) = 0x18cd080
--- SIGSEGV (Segmentation fault) ---
malloc(64) = 0x18ee010
-- <snip> --
The assembly listing for the 'new' allocation part is shown here. It was produced with the command 'gcc -S x1.adb'. You can see that it initializes the record after memory allocation. I assume that __gnat_malloc contains the check for the actual malloc failure. For this case, malloc was given 16 so I'm sure it has reached the part after 'call __gnat_malloc'. The line 'movq $0, 16(%rax)' violates the memory access for the first time as it's accessing beyond the 16 byte block allocated. I believe that the line is for 'Class => Null'. If it carried on, it would execute the code after the label .L53 starting from a few lines above it in a loop for 'Pointer_Slot => (others => null)'. That would also violate the memory access.
--<snip>--
call __gnat_malloc
movb $0, (%rax)
movq -840(%rbp), %rdx
movq %rdx, 8(%rax)
movzbl 1(%rax), %edx
andl $-8, %edx
movb %dl, 1(%rax)
movzbl 1(%rax), %edx
andl $-9, %edx
movb %dl, 1(%rax)
movzbl 1(%rax), %edx
andl $15, %edx
movb %dl, 1(%rax)
movq $0, 16(%rax)
movq -840(%rbp), %rdx
movq %rdx, %rcx
testq %rcx, %rcx
jle .L52
movl $1, %edx
.L53:
movq %rdx, %rbx
addq $1, %rbx
movq $0, 8(%rax,%rbx,8)
cmpq %rdx, %rcx
je .L52
addq $1, %rdx
jmp .L53
--<snip>--
Valgrind fails more miserably with this program. Any comments?
Thanks again,
Hyung-Hwan
next prev parent reply other threads:[~2013-08-15 1:06 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-08-14 3:50 GNAT Allocation of a very large record hyunghwan.chung
2013-08-14 19:32 ` Per Sandberg
2013-08-14 20:08 ` Anh Vo
2013-08-15 1:06 ` Hyung-Hwan Chung [this message]
2013-08-15 8:59 ` Georg Bauhaus
2013-08-15 14:27 ` Robert A Duff
2013-08-16 1:18 ` Hyung-Hwan Chung
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox