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