Browse Source

thingies

master
Nick Hayashi 1 year ago
parent
commit
37191f734a
  1. 1
      alloc.h
  2. 2
      array.hpp
  3. 1
      file.h
  4. 83
      print.cpp
  5. 2
      print.h
  6. 1
      serialize.h
  7. 5
      string.h
  8. 1
      types.h
  9. 1
      util.h

1
alloc.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_ALLOC_H
#define ULE_ALLOC_H

2
array.hpp

@ -85,7 +85,7 @@ struct Array {
void removeAndShrink(u32 index) {
ULE_TYPES_H_FTAG;
for (u32 i = index + 1; i < this->length; i++) {
String::memcpy(this->data[i - 1], this->data[i], sizeof(T));
String::memcpy(&this->data[i - 1], &this->data[i], sizeof(T));
}
this->length--;
}

1
file.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_FILE_H
#define ULE_FILE_H

83
print.cpp

@ -63,15 +63,21 @@ void trace(String* string) {
#define BACKTRACE_MAX_FUNCTION_NAME_LENGTH 1024
HANDLE processHandle = GetCurrentProcess();
SymInitialize(processHandle, null, true);
SymSetOptions(SYMOPT_LOAD_LINES);
void* stack[BACKTRACE_MAX_FRAMES];
unsigned short numFrames = CaptureStackBackTrace(0, BACKTRACE_MAX_FRAMES, stack, null);
char buffer[sizeof(SYMBOL_INFO) + (BACKTRACE_MAX_FUNCTION_NAME_LENGTH - 1) * sizeof(TCHAR)];
char buffer[sizeof(SYMBOL_INFO) + BACKTRACE_MAX_FUNCTION_NAME_LENGTH*sizeof(TCHAR)];
SYMBOL_INFO* symbol = (SYMBOL_INFO*) buffer;
symbol->MaxNameLen = BACKTRACE_MAX_FUNCTION_NAME_LENGTH;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
// @TODO I believe that 'displacement' and line.LineNumber are supposed to be source code column numbers
// and line numbers respectively, but displacement doesn't work at all (seems like) and line.LineNumber
// is consistently off by a few lines. Perhaps it's post-processed source? I don't know. For now,
// filename + line.LineNUmber are printed and we hope that's enough, and understand the line #s are only
// approximate.
DWORD displacement;
IMAGEHLP_LINE64 line;
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
@ -81,25 +87,53 @@ void trace(String* string) {
if (SymGetLineFromAddr64(processHandle, address, &displacement, &line)) {
if (string == null) {
print("\tat %s in %s: line: %lu: address %0x%0X\n", symbol->Name, line.FileName, line.LineNumber, symbol->Address);
print(" %-30s %s:%u\n", symbol->Name, line.FileName, line.LineNumber);
} else {
string->appendf("\tat %s in %s: line: %lu: address %0x%0X\n", symbol->Name, line.FileName, line.LineNumber, symbol->Address);
string->appendf(" %-30s %s:%u\n", symbol->Name, line.FileName, line.LineNumber);
}
} else {
if (string == null) {
print("\tSymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
print("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address);
warn("SymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
print(" %-30s unknown file\n", symbol->Name);
} else {
string->appendf("\tSymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
string->appendf("\tat %s, address 0x%0X.\n", symbol->Name, symbol->Address);
warn("SymGetLineFromAddr64 returned error code %lu.\n", GetLastError());
string->appendf(" %-30s unknown file\n", symbol->Name);
}
}
}
#undef BACKTRACE_MAX_FUNCTION_NAME_LENGTH
}
#include <Minidumpapiset.h>
#include <tchar.h>
void writeMinidump(void* exceptionPointers) { // 'EXCEPTION_POINTERS*' actually
// create a file
EXCEPTION_POINTERS* ep = (EXCEPTION_POINTERS*) exceptionPointers;
HANDLE hFile = CreateFile(_T("MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
if ((hFile != null) && (hFile != INVALID_HANDLE_VALUE)) {
// carry on with creating the minidump
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = ep;
mdei.ClientPointers = FALSE;
MINIDUMP_TYPE mdt = MiniDumpNormal;
BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, mdt, (ep != 0) ? &mdei : 0, 0, 0);
if (!rv) {
println(_T("MiniDumpWriteDump failed. Error: %u"), GetLastError());
} else {
println(_T("MiniDump created."));
}
CloseHandle(hFile);
} else {
println(_T("Failed to CreateFile for MiniDump. Error: %u"), GetLastError());
}
}
#else
void writeMinidump(void* exceptionPointers) {} // stub... does nothing on Unix
// OSX and Linux stacktrace stuff.
#include <execinfo.h> // backtrace, backtrace_symbols
#include <cxxabi.h> // abi::__cxa_demangle
@ -169,17 +203,17 @@ void trace(String* string) {
continue;
} else {
println("warning: failed to demangle name: %s, exit status of attempt: %d", traces[i], status);
warn("warning: failed to demangle name: %s, exit status of attempt: %d", traces[i], status);
// just write back the original trace, un-demangled.
trace = traces[i];
}
}
if (string == null) {
print("%s\n", trace);
print(" %s\n", trace);
} else {
string->appendf("%s\n", trace);
string->appendf(" %s\n", trace);
}
}
@ -227,35 +261,6 @@ void setCustomDieBehavior(void (*dieBehavior)(const char* string)) {
customDie = dieBehavior;
}
#ifdef _WIN32
#include <Minidumpapiset.h>
#include <tchar.h>
static void writeMinidump(EXCEPTION_POINTERS* pep) {
// create a file
HANDLE hFile = CreateFile(_T("MiniDump.dmp"), GENERIC_READ | GENERIC_WRITE, 0, null, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
if ((hFile != null) && (hFile != INVALID_HANDLE_VALUE)) {
// carry on with creating the minidump
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = FALSE;
MINIDUMP_TYPE mdt = MiniDumpNormal;
BOOL rv = MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0);
if (!rv) {
println(_T("MiniDumpWriteDump failed. Error: %u"), GetLastError());
} else {
println(_T("MiniDump created."));
}
CloseHandle(hFile);
} else {
println(_T("Failed to CreateFile for MiniDump. Error: %u"), GetLastError());
}
}
#endif
// for fatal errors which may occur at runtime, even on a release binary.
// if a fatal error should not occur at runtime on a release binary, consider preferring 'massert'
// it's unclear when you should use asserts vs. die actually. idk man, they kinda do the same thing right now

2
print.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_PRINT_H
#define ULE_PRINT_H
@ -82,6 +83,7 @@ extern void println(const char* format, ...);
// Prints a stack trace, or concatenates the stack trace to |string| if it is not null.
extern void trace(String* string = null);
extern void writeMinidump(void* exceptionPointers);
// This ends the program and calls trace(). generally you should use 'massert' instead
extern void die(const char* format, ...);

1
serialize.h

@ -1,4 +1,5 @@
#pragma once
#ifdef ULE_CONFIG_OPTION_SERIALIZATION
#ifndef ULE_SERIALIZE_H
#define ULE_SERIALIZE_H

5
string.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_STRING_H
#define ULE_STRING_H
@ -259,7 +260,7 @@ public:
static inline const char* firstCharOccurence(const char* string, u32 length, char c) {
ULE_TYPES_H_FTAG;
for (s32 i = 0; i < length; i++) {
for (u32 i = 0; i < length; i++) {
const char* s = string + i;
if (*s == c) {
return s;
@ -852,7 +853,7 @@ public:
Capacity = LocalBufSize; \
} else { \
while (Capacity < new_capacity) { \
Capacity *= 1.5; \
Capacity = (s32)(Capacity * 1.5f); \
Data = (char*) STR_MEMALLOC((size_t) Capacity * sizeof(char)); \
} \
} \

1
types.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_TYPES_H
#define ULE_TYPES_H

1
util.h

@ -1,4 +1,5 @@
#pragma once
#ifndef ULE_UTIL_H
#define ULE_UTIL_H

Loading…
Cancel
Save