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