Closed
Description
Development Environment: Arch Linux(kernel 4.1) 64bit with ldc 0.15.1
This is my test code:
md.S
/*
* Internal regbuf layout
*/
#define JB_RSP 0*8
#define JB_RBX 1*8
#define JB_RBP 2*8
#define JB_R12 3*8
#define JB_R13 4*8
#define JB_R14 5*8
#define JB_R15 6*8
#define JB_PC 7*8
.file "md.S"
.text
/* setreg(regbuf env) */
.globl setreg
.type setreg, @function
.align 16
setreg:
/*
* Save registers.
*/
movq %rbx, (JB_RBX)(%rdi)
movq %rbp, (JB_RBP)(%rdi)
movq %r12, (JB_R12)(%rdi)
movq %r13, (JB_R13)(%rdi)
movq %r14, (JB_R14)(%rdi)
movq %r15, (JB_R15)(%rdi)
/* Save SP */
leaq 8(%rsp), %rdx
movq %rdx, (JB_RSP)(%rdi)
/* Save PC we are returning to */
movq (%rsp), %rax
movq %rax, (JB_PC)(%rdi)
xorq %rax, %rax
ret
.size _co_setjmp, .-_co_setjmp
/* regjmp(regbuf env, int val) */
.globl regjmp
.type regjmp, @function
.align 16
regjmp:
/*
* Restore registers.
*/
movq (JB_RBX)(%rdi), %rbx
movq (JB_RBP)(%rdi), %rbp
movq (JB_R12)(%rdi), %r12
movq (JB_R13)(%rdi), %r13
movq (JB_R14)(%rdi), %r14
movq (JB_R15)(%rdi), %r15
/* Set return value */
test %esi, %esi
mov $01, %eax
cmove %eax, %esi
mov %esi, %eax
movq (JB_PC)(%rdi), %rdx
movq (JB_RSP)(%rdi), %rsp
/* Jump to saved PC */
jmpq *%rdx
.size _co_longjmp, .-_co_longjmp
coro.d:
version( X86 ) {
alias void*[6] regbuf;
} else version( X86_64 ) {
alias void*[8] regbuf;
}
import std.stdio;
import std.c.stdlib;
extern(C) {
int setreg(ref regbuf);
void regjmp(ref regbuf, int);
}
enum {
STK_DEFAULT_SIZE = 64 * 1024
}
struct Context {
regbuf env;
void* stk;
}
class Fiber {
private:
Context ctx;
regbuf env;
public:
this() {
ctx.stk = calloc(1, STK_DEFAULT_SIZE);
if(setreg(ctx.env)) {
run();
}
ctx.env[0] = ctx.stk + STK_DEFAULT_SIZE;
}
void run() {
writeln("hello");
yield();
writeln("world");
yield();
}
void call() {
if(!setreg(env)) {
regjmp(ctx.env, 1);
}
}
void yield() {
if(!setreg(ctx.env)) {
regjmp(env, 1);
}
}
}
void main() {
Fiber fb = new Fiber();
fb.call();
writeln("step1 done");
fb.call();
writeln("step2 done");
}
The executable file compiled by dmd or ldc -g/-O can work properly, but with ldc, it will throw segmentfault.
And I have used objdump -d to get the assembly code of exe file, and I found the problem may be inside the following area:
401380: 74 0e je 401390 <_D4coro5Fiber6__ctorMFZC4coro5Fiber+0x60>
401382: 48 8b 44 24 10 mov 0x10(%rsp),%rax
401387: 48 8b 08 mov (%rax),%rcx
%rax = 0, how is it come?
Metadata
Metadata
Assignees
Labels
No labels