Cant call an assembly function in c++ code
-
I am trying to implement coroutines in c++ (I had to reinvent the wheel for my project). coroutine.h
class coroutine {
public:
void (*action1)(int);
Stack local_stack;
coroutine(void (*action)(int ), int id); ///< will create coroutine
~coroutine();
static void yield();
};coroutine.cpp
coroutine *global_coro;
fcontext_t context_array[2];
coroutine :: coroutine(void (*action)(int), int id)
{
global_coro=this;
action1=action;
fcontext_t f_ctx = make_fcontext(global_coro->local_stack.local_stack, 1000, global_coro->action1);//Save the current context of coroutine for the sake of making switch context.
// make_fcontext is in .S file taken from boost::context
context_array[0]=f_ctx; // Global Array to store the coroutine context so that i can switch the context
}coroutine::~coroutine(){}
void coroutine::yield(){
transfer_t tr = jump_fcontext(context_of_current_corotine, context_of_next_coroutine ); //Also in .S file
Following is my stack class which allocates a block of memory to every coroutine from a global Memory pool stack.h
extern MemoryPool memPoolObj;
class Stack {
public:
void *local_stack;
MemoryPool& m_memPool=memPoolObj;
Stack();
~Stack();
};Stack.cpp
#include "Stack.h"
MemoryPool memPoolObj;
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}
Stack::~Stack() {}Context.h
typedef void* fcontext_t;
struct transfer_t
{
fcontext_t fctx;
void * data;
};extern "C"
transfer_t jump_fcontext( fcontext_t const to, void * vp);
extern "C"
fcontext_t make_fcontext( void * sp, std::size_t size, void (* fn)( int) );Main.cpp
#include "coroutine.h"
void workPackage(int id){
printf("Coroutine with id %d is called\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after first yield\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after second yield\n", id);
}int main() {
coroutine Coro1(workPackage, 1);
coroutine Coro2(workPackage, 2);
printf("Main is finished \n");
}My program compiles but gives segmentation fault during execution. Valgrind gives the following information and i am not able to solve the problem. I will provide the assembly file also if needed. Any help would be appreciated
Use of uninitialised value of size 8
==24145== at 0x10922B: make_fcontext (in /home/user1/eclipse-workspace/coroutines/Debug/coroutines)
==24145== by 0x10912D -
I am trying to implement coroutines in c++ (I had to reinvent the wheel for my project). coroutine.h
class coroutine {
public:
void (*action1)(int);
Stack local_stack;
coroutine(void (*action)(int ), int id); ///< will create coroutine
~coroutine();
static void yield();
};coroutine.cpp
coroutine *global_coro;
fcontext_t context_array[2];
coroutine :: coroutine(void (*action)(int), int id)
{
global_coro=this;
action1=action;
fcontext_t f_ctx = make_fcontext(global_coro->local_stack.local_stack, 1000, global_coro->action1);//Save the current context of coroutine for the sake of making switch context.
// make_fcontext is in .S file taken from boost::context
context_array[0]=f_ctx; // Global Array to store the coroutine context so that i can switch the context
}coroutine::~coroutine(){}
void coroutine::yield(){
transfer_t tr = jump_fcontext(context_of_current_corotine, context_of_next_coroutine ); //Also in .S file
Following is my stack class which allocates a block of memory to every coroutine from a global Memory pool stack.h
extern MemoryPool memPoolObj;
class Stack {
public:
void *local_stack;
MemoryPool& m_memPool=memPoolObj;
Stack();
~Stack();
};Stack.cpp
#include "Stack.h"
MemoryPool memPoolObj;
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}
Stack::~Stack() {}Context.h
typedef void* fcontext_t;
struct transfer_t
{
fcontext_t fctx;
void * data;
};extern "C"
transfer_t jump_fcontext( fcontext_t const to, void * vp);
extern "C"
fcontext_t make_fcontext( void * sp, std::size_t size, void (* fn)( int) );Main.cpp
#include "coroutine.h"
void workPackage(int id){
printf("Coroutine with id %d is called\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after first yield\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after second yield\n", id);
}int main() {
coroutine Coro1(workPackage, 1);
coroutine Coro2(workPackage, 2);
printf("Main is finished \n");
}My program compiles but gives segmentation fault during execution. Valgrind gives the following information and i am not able to solve the problem. I will provide the assembly file also if needed. Any help would be appreciated
Use of uninitialised value of size 8
==24145== at 0x10922B: make_fcontext (in /home/user1/eclipse-workspace/coroutines/Debug/coroutines)
==24145== by 0x10912D -
Where is the code for
make_fcontext
, which is shown as the place where the error occurs?My project structure in eclipse is as follows
Coroutines
Src
DebugCode for make_fcontext is in src folder in file "make_x86_64_sysv_elf_gas.S"
.text
.globl make_fcontext
.type make_fcontext,@function
.align 16
make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movq %rdi, %rax/\* shift address in RAX to lower 16 byte boundary \*/ andq $-16, %rax /\* reserve space for context-data on context-stack \*/ /\* on context-function entry: (RSP -0x8) % 16 == 0 \*/ leaq -0x40(%rax), %rax /\* third arg of make\_fcontext() == address of context-function \*/ /\* stored in RBX \*/ movq %rdx, 0x28(%rax) /\* save MMX control- and status-word \*/ stmxcsr (%rax) /\* save x87 control-word \*/ fnstcw 0x4(%rax) /\* compute abs address of label trampoline \*/ leaq trampoline(%rip), %rcx /\* save address of trampoline as return-address for context-function \*/ /\* will be entered after calling jump\_fcontext() first time \*/ movq %rcx, 0x38(%rax) /\* compute abs address of label finish \*/ leaq finish(%rip), %rcx /\* save address of finish as return-address for context-function \*/ /\* will be entered after context-function returns \*/ movq %rcx, 0x30(%rax) ret /\* return pointer to context-data \*/
trampoline:
/* store return address on stack */
/* fix stack alignment */
push %rbp
/* jump to context-function */
jmp *%rbxfinish:
/* exit code is zero */
xorq %rdi, %rdi
/* exit application */
call _exit@PLT
hlt
.size make_fcontext,.-make_fcontext/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits -
My project structure in eclipse is as follows
Coroutines
Src
DebugCode for make_fcontext is in src folder in file "make_x86_64_sysv_elf_gas.S"
.text
.globl make_fcontext
.type make_fcontext,@function
.align 16
make_fcontext:
/* first arg of make_fcontext() == top of context-stack */
movq %rdi, %rax/\* shift address in RAX to lower 16 byte boundary \*/ andq $-16, %rax /\* reserve space for context-data on context-stack \*/ /\* on context-function entry: (RSP -0x8) % 16 == 0 \*/ leaq -0x40(%rax), %rax /\* third arg of make\_fcontext() == address of context-function \*/ /\* stored in RBX \*/ movq %rdx, 0x28(%rax) /\* save MMX control- and status-word \*/ stmxcsr (%rax) /\* save x87 control-word \*/ fnstcw 0x4(%rax) /\* compute abs address of label trampoline \*/ leaq trampoline(%rip), %rcx /\* save address of trampoline as return-address for context-function \*/ /\* will be entered after calling jump\_fcontext() first time \*/ movq %rcx, 0x38(%rax) /\* compute abs address of label finish \*/ leaq finish(%rip), %rcx /\* save address of finish as return-address for context-function \*/ /\* will be entered after context-function returns \*/ movq %rcx, 0x30(%rax) ret /\* return pointer to context-data \*/
trampoline:
/* store return address on stack */
/* fix stack alignment */
push %rbp
/* jump to context-function */
jmp *%rbxfinish:
/* exit code is zero */
xorq %rdi, %rdi
/* exit application */
call _exit@PLT
hlt
.size make_fcontext,.-make_fcontext/* Mark that we don't need executable stack. */
.section .note.GNU-stack,"",%progbits -
I am trying to implement coroutines in c++ (I had to reinvent the wheel for my project). coroutine.h
class coroutine {
public:
void (*action1)(int);
Stack local_stack;
coroutine(void (*action)(int ), int id); ///< will create coroutine
~coroutine();
static void yield();
};coroutine.cpp
coroutine *global_coro;
fcontext_t context_array[2];
coroutine :: coroutine(void (*action)(int), int id)
{
global_coro=this;
action1=action;
fcontext_t f_ctx = make_fcontext(global_coro->local_stack.local_stack, 1000, global_coro->action1);//Save the current context of coroutine for the sake of making switch context.
// make_fcontext is in .S file taken from boost::context
context_array[0]=f_ctx; // Global Array to store the coroutine context so that i can switch the context
}coroutine::~coroutine(){}
void coroutine::yield(){
transfer_t tr = jump_fcontext(context_of_current_corotine, context_of_next_coroutine ); //Also in .S file
Following is my stack class which allocates a block of memory to every coroutine from a global Memory pool stack.h
extern MemoryPool memPoolObj;
class Stack {
public:
void *local_stack;
MemoryPool& m_memPool=memPoolObj;
Stack();
~Stack();
};Stack.cpp
#include "Stack.h"
MemoryPool memPoolObj;
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}
Stack::~Stack() {}Context.h
typedef void* fcontext_t;
struct transfer_t
{
fcontext_t fctx;
void * data;
};extern "C"
transfer_t jump_fcontext( fcontext_t const to, void * vp);
extern "C"
fcontext_t make_fcontext( void * sp, std::size_t size, void (* fn)( int) );Main.cpp
#include "coroutine.h"
void workPackage(int id){
printf("Coroutine with id %d is called\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after first yield\n", id);
coroutine::yield();
printf("Coroutine with id %d is resumed after second yield\n", id);
}int main() {
coroutine Coro1(workPackage, 1);
coroutine Coro2(workPackage, 2);
printf("Main is finished \n");
}My program compiles but gives segmentation fault during execution. Valgrind gives the following information and i am not able to solve the problem. I will provide the assembly file also if needed. Any help would be appreciated
Use of uninitialised value of size 8
==24145== at 0x10922B: make_fcontext (in /home/user1/eclipse-workspace/coroutines/Debug/coroutines)
==24145== by 0x10912DA quick glance brings up a problem here:
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}Perhaps I misunderstand the intention, but shouldn't this be:
Stack::Stack()
: local_stack(m_memPool.Allocate())
{} -
A quick glance brings up a problem here:
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}Perhaps I misunderstand the intention, but shouldn't this be:
Stack::Stack()
: local_stack(m_memPool.Allocate())
{} -
A quick glance brings up a problem here:
Stack::Stack() {
auto *local_stack= m_memPool.Allocate();
}Perhaps I misunderstand the intention, but shouldn't this be:
Stack::Stack()
: local_stack(m_memPool.Allocate())
{}