I would like to use Mach threads in one of my applications. However, I'm having trouble getting a simple "Hello, world" program using Mach threads to work on OS X 10.9.4. The following MWE always crashes with a segmentation fault. Perhaps I am not setting up the stack correctly, but I can't figure out where I'm going wrong. Do you have any ideas?
Thanks for your help!
- Code: Select all
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <mach/mach_init.h>
#include <mach/mach_types.h>
#include <mach/task.h>
#include <mach/thread_act.h>
#include <mach/thread_policy.h>
#include <mach/i386/thread_status.h>
void check(kern_return_t err)
{
if (err == KERN_SUCCESS) {
return;
}
switch (err) {
case KERN_FAILURE:
fprintf(stderr, "failure");
case KERN_INVALID_ARGUMENT:
fprintf(stderr, "invalid argument");
default:
fprintf(stderr, "unknown error");
}
exit(EXIT_FAILURE);
}
void test()
{
printf("Hello, world!");
}
int main()
{
thread_t thread;
int page_size = getpagesize();
uint8_t* stack = (uint8_t*)malloc(page_size);
task_t task = mach_task_self();
check(thread_create(task, &thread));
x86_thread_state64_t state;
mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
check(thread_get_state(thread, x86_THREAD_STATE64,
(thread_state_t)&state, &count));
uintptr_t stack_ptr = (uintptr_t)(stack + page_size);
stack_ptr &= -16;
stack_ptr -= sizeof(void*);
state.__rip = (uintptr_t)test;
state.__rsp = (uintptr_t)stack_ptr;
state.__rbp = (uintptr_t)stack_ptr;
check(thread_set_state(thread, x86_THREAD_STATE64,
(thread_state_t)&state, x86_THREAD_STATE64_COUNT));
check(thread_resume(thread));
// Give the thread a chance to run.
sleep(1);
printf("Done.");
}