Я пытаюсь написать простое «Привет, мир!» программа, использующая потоки Маха на x86_64. К сожалению, программа вылетает с ошибкой сегментации на моей машине, и я не могу решить проблему. Я не смог найти много документации по темам Маха онлайн, но я сослался на следующее C файл который также использует потоки Маха.
Насколько я могу сказать, я все делаю правильно. Я подозреваю, что ошибка сегментации заключается в том, что я неправильно настроил стек потока, но я использовал тот же подход, что и эталонный файл, который имеет следующий код.
// This is for alignment. In particular note that the sizeof(void*) is necessary
// since it would usually specify the return address (i.e. we are aligning the call
// frame to a 16 byte boundary as required by the abi, but the stack pointer
// to point to the byte beyond that. Not doing this leads to funny behavior on
// the first access to an external function will fail due to stack misalignment
state.__rsp &= -16;
state.__rsp -= sizeof(void*);
Есть ли у вас какие-либо идеи относительно того, что я могу делать неправильно?
#include <cstdint>
#include <iostream>
#include <system_error>
#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;
}
auto code = std::error_code{err, std::system_category()};
switch (err) {
case KERN_FAILURE:
throw std::system_error{code, "failure"};
case KERN_INVALID_ARGUMENT:
throw std::system_error{code, "invalid argument"};
default:
throw std::system_error{code, "unknown error"};
}
}
void test()
{
std::cout << "Hello from thread." << std::endl;
}
int main()
{
auto page_size = ::getpagesize();
auto stack = new uint8_t[page_size];
auto thread = ::thread_t{};
auto task = ::mach_task_self();
check(::thread_create(task, &thread));
auto state = ::x86_thread_state64_t{};
auto count = ::mach_msg_type_number_t{x86_THREAD_STATE64_COUNT};
check(::thread_get_state(thread, x86_THREAD_STATE64,
(::thread_state_t)&state, &count));
auto 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));
::sleep(1);
std::cout << "Done." << std::endl;
}
Ссылочный файл использует C ++ 11; при компиляции с GCC или Clang, вам нужно будет предоставить std=c++11
флаг.
Задача ещё не решена.