AuroraRuntime/Source/Debug/Stack.Unix.cpp

125 lines
2.9 KiB
C++
Raw Normal View History

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: Stack.Unix.cpp
Date: 2022-1-26
Author: Reece
***/
Further Linux support [+] Begin work on IO futexes for io release on process/thread exit [+] Linux ::readdir iteration [+] AuConsole buffering API [*] Fix sleep as to not get interrupted by signals [*] Switch the type of FS lock used under Linux [*] Linux: Use new IPCHandle encoding scheme [*] Fix undefined behaviour: unintialized timeout values (AuLoop/Linux) [*] Fix undefined behaviour: ConsoleTTY clear line was called of a color of a random value on stack [-] Remainings of std dir iterator [*] Fix pthread_kill (aka send signal to pthread handle) always kills process. This is what you expect bc signal handler inheritance. [*] Reformat the build Aurora.json file [+] Added clang warning ignores to the build file [*] Fix: UNIX need to use STDOUT_FILENO. Was using CRT handle in place of fd by mistake. [+] Linux implementation for IO yield (AuIO::IOYield() - UNIX::LinuxOverlappedYield()) [*] Fix: Linux async end of stream processing. res 0 = zero bytes consumed. <= was detecting this as an error of code 0. Should succeed with zero bytes. [+] Linux LoopQueue missing epilogue hook for the IO processor [*] Various refactors and minor bug fixes [*] Linux fix: Handle pipe EOS as zero [*] Linux fix: thread termination via a user signal of 77. Need a force terminate. [*] IPC handle: fix improper int to bool cast in the header setup within ToString [*] Linux fix: HWInfo CPU topology regression [-] Linux fix: remove SIGABRT handler [*] Missing override in compression, exit, and consoletty headers. [+] Unix Syslog logger backend
2022-08-02 04:52:17 +00:00
#include <Source/RuntimeInternal.hpp>
#include "Stack.hpp"
#include "Stack.Unix.hpp"
#include <libunwind.h>
#include <dlfcn.h>
namespace Aurora::Debug
{
static void TryComplete(StackTraceEntry &entry)
{
}
static StackTrace DumpContext(unw_context_t *uc)
{
StackTrace ret;
unw_cursor_t cursor;
unw_word_t ip;
::unw_init_local(&cursor, uc);
while (::unw_step(&cursor) > 0)
{
StackTraceEntry entry;
::unw_get_reg(&cursor, UNW_REG_IP, &ip);
// module
{
unw_word_t off;
char procName[512];
if (unw_get_proc_name(&cursor, procName, AuArraySize(procName), &off) == 0)
{
AuString str;
str = AuString(procName, strlen(procName));
str += fmt::format("+0x{:x}", off);
entry.label = str;
}
}
{
Dl_info dlinfo;
AuSInt originalIP {};
AuUInt moduleAddress {};
const char *dllPathName {};
if (::dladdr((const void *)ip, &dlinfo))
{
dllPathName = dlinfo.dli_fname;
moduleAddress = (AuUInt)dlinfo.dli_fbase;
originalIP = (AuUInt)ip - moduleAddress;
}
entry.address = ip;
entry.relAddress = originalIP;
if (dllPathName)
{
entry.module = dllPathName;
}
}
AuTryInsert(ret, entry);
}
return ret;
}
StackTrace DumpContextPlatform(ucontext_t &uc)
{
// VALID:
// Linux: https://github.com/libunwind/libunwind/blob/3be832395426b72248969247a4a66e3c3623578d/include/libunwind-x86.h#L170
// ???
// MACOS: https://github.com/JuliaLang/libosxunwind/blob/master/include/libunwind.h#L57
return DumpContext((unw_context_t *)&uc);
}
StackTrace PlatformWalkCallStack()
{
#if 0
StackTrace ret;
void *ips[1024];
int count = ::backtrace(ips, AuArraySize(ips));
auto messages = ::backtrace_symbols(ips, count);
if (!messages)
{
return {};
}
for (int i = 0; i < count; i++)
{
StackTraceEntry entry;
entry.address = AuUInt64(ips[i]);
entry.label = AuUInt64(messages[i]);
TryComplete(entry);
AuTryInsert(ret, entry);
}
free(messages);
return ret;
#endif
::unw_context_t uc;
::unw_getcontext(&uc);
return DumpContext(&uc);
}
}