Skip to content

Commit

Permalink
chore: Commit unfinished code
Browse files Browse the repository at this point in the history
Work-in-progress code for debugging, but abandoned as
the process is too complicated and undocumented by Haiku.

Compiles well so should be mostly harmless.
  • Loading branch information
trungnt2910 committed Jan 17, 2023
1 parent 944c5b1 commit 5ca058d
Show file tree
Hide file tree
Showing 8 changed files with 923 additions and 17 deletions.
104 changes: 97 additions & 7 deletions hyclone_server/port.cpp
Expand Up @@ -25,20 +25,21 @@ Port::Port(int pid, int capacity, const char* name)
_info.port = 0;
}

void Port::Write(std::vector<char>&& message)
void Port::Write(int code, std::vector<char>&& message)
{
_messages.emplace(std::move(message));
_messages.emplace(code, std::move(message));
++_info.queue_count;
}

std::vector<char> Port::Read()
std::pair<int, std::vector<char>> Port::Read()
{
assert(_info.queue_count > 0);
--_info.queue_count;
++_info.total_count;
std::vector<char> result = std::move(_messages.front());
std::vector<char> resultData = std::move(_messages.front().second);
int resultCode = _messages.front().first;
_messages.pop();
return result;
return std::make_pair(resultCode, std::move(resultData));
}

intptr_t server_hserver_call_create_port(hserver_context& context, int32 queue_length, const char *name, size_t portNameLength)
Expand Down Expand Up @@ -228,7 +229,7 @@ intptr_t server_hserver_call_write_port_etc(hserver_context& context, port_id id
auto lock = port->Lock();
if (port->GetInfo().queue_count < port->GetInfo().capacity)
{
port->Write(std::move(message));
port->Write(messageCode, std::move(message));
return B_OK;
}
}
Expand Down Expand Up @@ -258,7 +259,7 @@ intptr_t server_hserver_call_write_port_etc(hserver_context& context, port_id id
auto lock = port->Lock();
if (port->GetInfo().queue_count < port->GetInfo().capacity)
{
port->Write(std::move(message));
port->Write(messageCode, std::move(message));
return B_OK;
}
}
Expand All @@ -277,3 +278,92 @@ intptr_t server_hserver_call_write_port_etc(hserver_context& context, port_id id
std::cerr << "server_hserver_call_write_port_etc: Impossible code path reached." << std::endl;
return B_BAD_DATA;
}

intptr_t server_hserver_call_read_port_etc(hserver_context& context,
port_id id, int32* userMessageCode, void *msgBuffer,
size_t bufferSize, uint32 flags, unsigned long long timeout)
{
bool useTimeout = (bool)(flags & B_TIMEOUT);
const int sleepTimeMicroseconds = 100 * 1000; // 100ms, in microseconds.

std::weak_ptr<Port> weak_port;

{
auto& system = System::GetInstance();
auto lock = system.Lock();
weak_port = system.GetPort(id);
}

int32 messageCode;
std::vector<char> message;

{
auto port = weak_port.lock();

if (!port)
{
return B_BAD_PORT_ID;
}

{
auto lock = port->Lock();
if (port->GetInfo().queue_count > 0)
{
std::tie(messageCode, message) = port->Read();
goto good;
}
}
}

if (useTimeout && (timeout == 0))
{
return B_WOULD_BLOCK;
}

while (!useTimeout || (timeout > 0))
{
server_worker_sleep(sleepTimeMicroseconds);
{
auto port = weak_port.lock();

if (!port)
{
return B_BAD_PORT_ID;
}

{
auto lock = port->Lock();
if (port->GetInfo().queue_count < port->GetInfo().capacity)
{
std::tie(messageCode, message) = port->Read();
goto good;
}
}
}
if (timeout > sleepTimeMicroseconds)
{
timeout -= sleepTimeMicroseconds;
}
else
{
return B_TIMED_OUT;
}
}

// Should not reach here.
std::cerr << "server_hserver_call_read_port_etc: Impossible code path reached." << std::endl;
return B_BAD_DATA;

good:
if (context.process->WriteMemory(&userMessageCode, &messageCode, sizeof(messageCode)) != sizeof(int32))
{
return B_BAD_ADDRESS;
}

if (context.process->WriteMemory(msgBuffer, message.data(), std::min(message.size(), bufferSize)) != message.size())
{
return B_BAD_ADDRESS;
}

return B_OK;
}
6 changes: 3 additions & 3 deletions hyclone_server/port.h
Expand Up @@ -16,16 +16,16 @@ class Port
friend class System;
private:
haiku_port_info _info;
std::queue<std::vector<char>> _messages;
std::queue<std::pair<int, std::vector<char>>> _messages;
std::mutex _lock;
public:
Port(int pid, int capacity, const char* name);
~Port() = default;

std::unique_lock<std::mutex> Lock() { return std::unique_lock(_lock); }

void Write(std::vector<char>&& message);
std::vector<char> Read();
void Write(int code, std::vector<char>&& message);
std::pair<int, std::vector<char>> Read();

std::string GetName() const { return _info.name; }
const haiku_port_info& GetInfo() const { return _info; }
Expand Down
85 changes: 80 additions & 5 deletions monika/linux/debug.cpp
@@ -1,12 +1,31 @@
#include <cstddef>
#include <string.h>
#include <signal.h>

#include "BeDefs.h"
#include "debugbreak.h"
#include "export.h"
#include "haiku_debugger.h"
#include "haiku_errors.h"
#include "linux_debug.h"
#include "linux_subsystemlock.h"
#include "linux_syscall.h"
#include "thread_defs.h"

static bool sIsProcessDebugged = false;
static int sDebugSubsystemLock = HYCLONE_SUBSYSTEM_LOCK_UNINITIALIZED;

static int32 NubThreadEntry(void* arg1, void* arg2);

extern "C"
{


extern thread_id _kern_spawn_thread(struct thread_creation_attributes* attributes);
extern status_t _kern_resume_thread(thread_id thread);
extern size_t _kern_read_port_etc(port_id port, int32 *msgCode,
void *msgBuffer, size_t bufferSize, uint32 flags,
bigtime_t timeout);

void MONIKA_EXPORT _kern_debug_output(const char* userString)
{
size_t len = strlen(userString);
Expand All @@ -17,11 +36,67 @@ void MONIKA_EXPORT _kern_debug_output(const char* userString)

void MONIKA_EXPORT _kern_debugger(const char* userString)
{
size_t len = strlen(userString);
const char prefix[] = "_kern_debugger: ";
LINUX_SYSCALL3(__NR_write, 2, prefix, sizeof(prefix));
LINUX_SYSCALL3(__NR_write, 2, userString, len);
if (!sIsProcessDebugged)
{
size_t len = strlen(userString);
const char prefix[] = "_kern_debugger: ";
LINUX_SYSCALL3(__NR_write, 2, prefix, sizeof(prefix));
LINUX_SYSCALL3(__NR_write, 2, userString, len);
}

debug_break();
}

status_t MONIKA_EXPORT __monika_spawn_nub_thread(port_id id)
{
{
auto lock = SubsystemLock(sDebugSubsystemLock);
if (sIsProcessDebugged)
{
return B_NOT_ALLOWED;
}

sIsProcessDebugged = true;
}
struct thread_creation_attributes attributes;
memset(&attributes, 0, sizeof(attributes));

attributes.args1 = (void*)(intptr_t)id;
attributes.name = "team debug task";
attributes.entry = NubThreadEntry;

thread_id thread_id = _kern_spawn_thread(&attributes);
_kern_resume_thread(id);

int tid = LINUX_SYSCALL0(__NR_gettid);

LINUX_SYSCALL3(__NR_tgkill, -1, tid, SIGINT);

return B_OK;
}

}

// Forwards everything back to the server.
// On Haiku, the nub thread should be an in-process
// thread that handles these operation, the fact that
// this function forwards the operations to the kernel server
// is Hyclone's implementation detail.
int NubThreadEntry(void* arg1, void* arg2)
{
port_id port = (port_id)(intptr_t)arg1;

while (sIsProcessDebugged)
{
int command;
debug_nub_message_data data;

if (_kern_read_port_etc(port, &command, &data, sizeof(data), 0, 0) < 0)
{
continue;
}

panic("NubThreadEntry: unimplemented");
// GET_SERVERCALLS()->debug_process_nub_message(command, &data);
}
}
7 changes: 7 additions & 0 deletions monika/linux/ipc.cpp
Expand Up @@ -19,6 +19,13 @@ port_id MONIKA_EXPORT _kern_create_port(int32 queue_length, const char *name)
return GET_SERVERCALLS()->create_port(queue_length, name, strlen(name));
}

size_t MONIKA_EXPORT _kern_read_port_etc(port_id port, int32 *msgCode,
void *msgBuffer, size_t bufferSize, uint32 flags,
bigtime_t timeout)
{
return GET_SERVERCALLS()->read_port_etc(port, msgCode, msgBuffer, bufferSize, flags, timeout);
}

status_t MONIKA_EXPORT _kern_write_port_etc(port_id port, int32 messageCode, const void *msgBuffer,
size_t bufferSize, uint32 flags, bigtime_t timeout)
{
Expand Down
2 changes: 1 addition & 1 deletion monika/linux/stubs.cpp
Expand Up @@ -161,7 +161,7 @@ SYSCALL_STUB(_kern_read_attr)
//SYSCALL_STUB(_kern_read_index_stat)
SYSCALL_STUB(_kern_read_kernel_image_symbols)
//SYSCALL_STUB(_kern_read_link)
SYSCALL_STUB(_kern_read_port_etc)
//SYSCALL_STUB(_kern_read_port_etc)
//SYSCALL_STUB(_kern_read_stat)
SYSCALL_STUB(_kern_readv)
SYSCALL_STUB(_kern_realtime_sem_close)
Expand Down

0 comments on commit 5ca058d

Please sign in to comment.