Segmentation error creating user level thread with C and assembly

I am trying to understand some basics of the OS using some tasks. I have already posted a similar question and received satisfactory answers. But it is a little different, but I could not debug it. So here is what I do:

What I want to do is run the main program, malloc space, use it as a stack to start a user level thread. My problem is with the return address. Here's the code for now:

[I am editing my code so that it is updated to the current state of my response]

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define STACK_SIZE 512

void switch_thread(int*,int*);

int k = 0;

void simple_function()
{
    printf("I am the function! k is: %d\n",k);
    exit(0);
}

void create_thread(void (*function)())
{   
   int* stack = malloc(STACK_SIZE + 32);
   stack = (int* )(((long)stack & (-1 << 4)) + 0x10);
   stack = (int* ) ((long)stack + STACK_SIZE); 
   *stack = (long) function;
   switch_thread(stack,stack);  
}

int main()
{
    create_thread(simple_function);
    assert(0);
    return 0;
}

switch_thread is the assembly code that I wrote as follows:

.text
    .globl  switch_thread
switch_thread:  
    movq    %rdi, %rsp
    movq    %rsi, %rbp
    ret

GDB ( simple_function " - ! k is: 0". . .

. .

+5
2

:

  • ( ), , " ". % rbp , .

  • , , ret, , % rsp, . , *(base_pointer + 1), *(base_pointer) , . , % rbp .

( ) :

void switch_thread(int* stack_pointer,int* entry_point);

void create_thread(void (*function)())
{
    int* stack_pointer = malloc(STACK_SIZE + 8);
    stack_pointer += STACK_SIZE; //you'd probably want to back up the original allocated address if you intend to free it later for any reason.
    switch_thread(stack_pointer,function);      
}

switch_thread :

    .text
    .globl  switch_thread
switch_thread:
    mov     %rsp, %rax //move the original stack pointer to a scratch register
    mov     %rdi, %rsp //set stack pointer
    push    %rax       //back-up the original stack pointer
    call    %rsi       //call the function
    pop     %rsp       //restore the original stack pointer
    ret                //return to create_thread

FYI: , , (, ntdll RtlUserThreadStart). , , .

+7

base_pointer void (*)(), undefined. , - :

void create_thread(void (*function)())
{
    size_t offset = STACK_SIZE + sizeof function - STACK_SIZE % sizeof function;
    char *stack_pointer = malloc(offset + sizeof *base_pointer);
    void (**base_pointer)() = stack_pointer + offset;
    *base_pointer = function;
    switch_thread(stack_pointer,base_pointer);      
}

malloc. , , .

, , , undefined.

0

All Articles