Segfault with std.container.Array but not regular dynamic array

Maxim Fomin maxim at maxim-fomin.ru
Thu Nov 29 07:06:06 PST 2012


On Thursday, 29 November 2012 at 12:38:03 UTC, Dan wrote:
> On Thursday, 29 November 2012 at 07:59:02 UTC, Maxim Fomin 
> wrote:
>
>> This doesn't look like assembly for previous source. Please 
>> provide the source for which you have assembly and tell which 
>> dmd options do you use.
>
> Well, I'm using the latest dmd (from the trunk), phobos, 
> druntime, so I could build and step through.
>

This is version generated by rdmd -version=bug --force 
--build-only -g -w -property. The only difference between this 
and yours is in <+71>.

<+00>:	push   %rbp
<+01>:	mov    %rsp,%rbp
<+04>:	sub    $0x38,%rsp
<+08>:	push   %rbx
// push 3 as a pkey, -0x30(%rbp) is 3
<+09>:	mov    $0x3,%eax
<+14>:	mov    %eax,-0x30(%rbp)
<+17>:	lea    -0x30(%rbp),%rcx
// push valuesize
<+21>:	movabs $0x8,%rdx
// push keyti
<+31>:	movabs $0x430f50,%rsi
// push map address, it is tls object
<+41>:	mov    %fs:0x0,%rdi
<+50>:	add    0x21e22f(%rip),%rdi        # 0x636fb0
// call, keyti=8, aa=&map, valuesize=8, pkey=3
<+57>:	callq  0x419140 <_aaGetX>
// store return value in -0x28(%rbp)
<+62>:	mov    %rax,-0x28(%rbp)
// check array bounds
<+66>:	test   %rax,%rax
<+69>:	jne    0x418d99 <_Dmain+81>
<+71>:	mov    $0x13,%edi
<+76>:	callq  0x418e28 <_D4main7__arrayZ>
// constructing S rhs for opAssign
<+81>:	movabs $0x2a,%rax
<+91>:	mov    %rax,-0x18(%rbp) // rhs
<+95>:	mov    %rax,%rsi
// making this from -0x20(%rbp), but it was stored in -0x28(%rbp)
<+98>:	lea    -0x20(%rbp),%rdi
// opAssign loads this from %rdi
<+102>:	callq  0x418ce0 <_D4main1S8opAssignMFS4main1SZv>
// replace content in -0x28(%rbp) by -0x20(%rbp)
<+107>:	mov    -0x20(%rbp),%rcx
<+111>:	mov    -0x28(%rbp),%rdx
<+115>:	mov    %rcx,(%rdx)
// load previously created object
<+118>:	movl   $0x3,-0x10(%rbp)
<+125>:	lea    -0x10(%rbp),%rcx
<+129>:	movabs $0x8,%rdx
<+139>:	movabs $0x430f50,%rsi
<+149>:	mov    %fs:0x0,%rax
<+158>:	mov    0x21e1c3(%rip),%rbx        # 0x636fb0
<+165>:	mov    (%rax,%rbx,1),%rdi
<+169>:	callq  0x4192b8 <_aaGetRvalueX>
// store pointer to existed object
<+174>:	mov    %rax,-0x8(%rbp)
// check array bounds
<+178>:	test   %rax,%rax
<+181>:	jne    0x418e09 <_Dmain+193>
<+183>:	mov    $0x14,%edi
<+188>:	callq  0x418e28 <_D4main7__arrayZ>
// load x member
<+193>:	mov    -0x8(%rbp),%rcx
<+197>:	mov    (%rcx),%rsi
<+200>:	movabs $0x430ac0,%rdi
<+210>:	xor    %eax,%eax
<+212>:	callq  0x4188e0 <printf at plt>
<+217>:	xor    %eax,%eax
<+219>:	pop    %rbx
<+220>:	leaveq
<+221>:	retq
End of assembler dump.

Main stack frame looks follows:
-0x30(%rbp):-0x28(%rbp) 3 as a pkey arg to _aaGetX
-0x28(%rbp):-0x20(%rbp) pointer to S allocated by _aaGetX
-0x20(%rbp):-0x18(%rbp) uninitialized struct - "this" ptr
-0x18(%rbp):-0x10(%rbp) constructed struct passed as rhs to 
opAssign
-0x10(%rbp):-0x08(%rbp) 3 as a pkey arg to _aaGetRvalueX
-0x08(%rbp):-0x00(%rbp) pointer to S returned from _aaGetRvalueX

It seems that dmd allocates space for two structs, one 
non-initialized, second initialized, issues call to druntime, 
then places a call to opAssign with non-initialized as "this" 
object with initialized as rhs argument, then writes content on 
non-initialized to allocated by druntime. So, this looks like a 
codegen bug.

By the way, if the code is compiled with command "dmd main -g 
-release -noboundscheck -version=bug", opAssign call is placed 
before calling _aaGetX.


More information about the Digitalmars-d-learn mailing list