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

Dan dbdavidson at yahoo.com
Thu Nov 29 12:40:45 PST 2012


On Thursday, 29 November 2012 at 15:06:07 UTC, Maxim Fomin wrote:
> 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.

Very educational - thanks!



More information about the Digitalmars-d-learn mailing list