Add stack trace, fix tracking for expandable arenas
This commit is contained in:
parent
493efe4d74
commit
8ebdcb27a8
@ -85,7 +85,6 @@ bool arena_commit_first_pages (Arena* arena, s64 commit_size, s64 start_offset)
|
|||||||
// Arena* bootstrap_arena (Arena_Reserve new_reserve, s32 default_commit_page_count) {
|
// Arena* bootstrap_arena (Arena_Reserve new_reserve, s32 default_commit_page_count) {
|
||||||
Arena* bootstrap_arena_internal (Arena_Reserve new_reserve, s32 default_commit_page_count, string file_path,
|
Arena* bootstrap_arena_internal (Arena_Reserve new_reserve, s32 default_commit_page_count, string file_path,
|
||||||
string function_name, s32 line_number) {
|
string function_name, s32 line_number) {
|
||||||
// #TODO: Store info in debug mode:
|
|
||||||
// + Save thread ID/name MAKE A COPY OBVIOUSLY! + PUSH default_allocator!
|
// + Save thread ID/name MAKE A COPY OBVIOUSLY! + PUSH default_allocator!
|
||||||
// WE USE default_allocator because this arena may be used to back an array!
|
// WE USE default_allocator because this arena may be used to back an array!
|
||||||
s64 commit_size = default_commit_page_count * PLATFORM_MEMORY_PAGE_SIZE;
|
s64 commit_size = default_commit_page_count * PLATFORM_MEMORY_PAGE_SIZE;
|
||||||
@ -103,12 +102,14 @@ Arena* bootstrap_arena_internal (Arena_Reserve new_reserve, s32 default_commit_p
|
|||||||
|
|
||||||
arena_set_bootstrap_flag(arena_ptr);
|
arena_set_bootstrap_flag(arena_ptr);
|
||||||
|
|
||||||
// #if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
// { push_allocator(default_allocator());
|
// #TODO: use thread_context()->stack_trace if present instead?
|
||||||
// arena_ptr->file_path = copy_string(file_path);
|
{ arena_ptr->file_path = file_path;
|
||||||
// arena_ptr->function_name =
|
arena_ptr->function_name = function_name;
|
||||||
// }
|
arena_ptr->line_number = line_number;
|
||||||
// #endif
|
add_arena_to_in_use_list(arena_ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return arena_ptr;
|
return arena_ptr;
|
||||||
}
|
}
|
||||||
@ -322,3 +323,22 @@ void* fixed_arena_allocator_proc (Allocator_Mode mode, s64 requested_size, s64 o
|
|||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
force_inline void initialize_arenas_in_use_list () {
|
||||||
|
if (arenas_in_use.allocated > 0) return;
|
||||||
|
mutex_init(&arenas_in_use_mutex);
|
||||||
|
arenas_in_use.allocator = default_allocator();
|
||||||
|
array_reserve(arenas_in_use, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
force_inline void add_arena_to_in_use_list (Arena* arena) {
|
||||||
|
Assert(arenas_in_use.allocated > 0); // check we initialized!
|
||||||
|
lock_guard(&arenas_in_use_mutex);
|
||||||
|
array_add(arenas_in_use, arena);
|
||||||
|
}
|
||||||
|
|
||||||
|
force_inline void remove_arena_from_in_use_list (Arena* arena) {
|
||||||
|
Assert(arenas_in_use.allocated > 0); // check we initialized!
|
||||||
|
lock_guard(&arenas_in_use_mutex);
|
||||||
|
array_unordered_remove_by_value(arenas_in_use, arena, 1);
|
||||||
|
}
|
||||||
|
|||||||
@ -184,3 +184,12 @@ s64 committed_bytes (ArrayView<Arena*> arenas) {
|
|||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
global Mutex arenas_in_use_mutex;
|
||||||
|
global Array<Arena*> arenas_in_use;
|
||||||
|
|
||||||
|
force_inline void initialize_arenas_in_use_list ();
|
||||||
|
force_inline void add_arena_to_in_use_list(Arena* arena);
|
||||||
|
force_inline void remove_arena_from_in_use_list (Arena* arena);
|
||||||
|
#endif
|
||||||
|
|||||||
@ -60,6 +60,14 @@ void free_pages_down_to (Arena* arena, s64 pages_to_keep) {
|
|||||||
|
|
||||||
void arena_delete (Arena* arena) {
|
void arena_delete (Arena* arena) {
|
||||||
if (!is_valid(arena)) return;
|
if (!is_valid(arena)) return;
|
||||||
|
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
{ //default_allocator_free(arena->file_path.data);
|
||||||
|
//default_allocator_free(arena->function_name.data);
|
||||||
|
remove_arena_from_in_use_list(arena);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
bool arena_was_boostrapped = (arena->flags & Arena_Flags::Is_Bootstrapped) == Arena_Flags::Is_Bootstrapped;
|
bool arena_was_boostrapped = (arena->flags & Arena_Flags::Is_Bootstrapped) == Arena_Flags::Is_Bootstrapped;
|
||||||
|
|
||||||
// s64 size_tmp = reserve_size(arena);
|
// s64 size_tmp = reserve_size(arena);
|
||||||
|
|||||||
@ -235,7 +235,6 @@ void array_unordered_remove_by_index (Array<T>& src, s64 index) {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
s64 array_unordered_remove_by_value (Array<T>& src, T item, s64 max_count_to_remove) {
|
s64 array_unordered_remove_by_value (Array<T>& src, T item, s64 max_count_to_remove) {
|
||||||
s64 removed_count = 0;
|
s64 removed_count = 0;
|
||||||
|
|
||||||
for (s64 i = 0; i < src.count; i += 1) {
|
for (s64 i = 0; i < src.count; i += 1) {
|
||||||
if (src[i] == item) {
|
if (src[i] == item) {
|
||||||
removed_count += 1;
|
removed_count += 1;
|
||||||
|
|||||||
@ -15,6 +15,9 @@ internal void Bootstrap_Main_Thread_Context () {
|
|||||||
// memset(arena_free_list, 0, sizeof(Arena_Free_List));
|
// memset(arena_free_list, 0, sizeof(Arena_Free_List));
|
||||||
// initialize_arena_free_list(default_allocator());
|
// initialize_arena_free_list(default_allocator());
|
||||||
|
|
||||||
|
// 1b. Setup arena in-use list:
|
||||||
|
initialize_arenas_in_use_list();
|
||||||
|
|
||||||
// 2. #NewContext Setup thread local context
|
// 2. #NewContext Setup thread local context
|
||||||
ExpandableArena* arena_ex = bootstrap_expandable_arena(Arena_Reserve::Size_64M);
|
ExpandableArena* arena_ex = bootstrap_expandable_arena(Arena_Reserve::Size_64M);
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,17 @@
|
|||||||
// #hacky fwd declares
|
// #hacky fwd declares
|
||||||
|
struct Source_Code_Location {
|
||||||
|
string file_name;
|
||||||
|
string function_name;
|
||||||
|
s32 line_number;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Stack_Trace_Node {
|
||||||
|
Stack_Trace_Node* next;
|
||||||
|
// Information
|
||||||
|
Source_Code_Location data;
|
||||||
|
s32 call_depth;
|
||||||
|
};
|
||||||
|
|
||||||
struct Error;
|
struct Error;
|
||||||
struct Graphics;
|
struct Graphics;
|
||||||
|
|
||||||
@ -12,7 +25,7 @@ struct Thread_Context {
|
|||||||
u16 default_allocator_alignment = 16;
|
u16 default_allocator_alignment = 16;
|
||||||
Logger logger = {nullptr, nullptr};
|
Logger logger = {nullptr, nullptr};
|
||||||
String_Builder* log_builder;
|
String_Builder* log_builder;
|
||||||
// Stack_Trace* stack_trace;
|
Stack_Trace_Node* stack_trace; // use `list(stack_trace)` in watch window of raddbg to view as array!
|
||||||
|
|
||||||
Array<Thread*> child_threads; // maybe should be linked-list?
|
Array<Thread*> child_threads; // maybe should be linked-list?
|
||||||
Thread_Context* parent_thread_context = nullptr; // so we can remove from above array
|
Thread_Context* parent_thread_context = nullptr; // so we can remove from above array
|
||||||
@ -44,12 +57,112 @@ struct Push_Allocator {
|
|||||||
|
|
||||||
Push_Allocator (Allocator new_allocator) {
|
Push_Allocator (Allocator new_allocator) {
|
||||||
context = thread_context();
|
context = thread_context();
|
||||||
|
if (this->context != nullptr) {
|
||||||
old_allocator = context->allocator;
|
old_allocator = context->allocator;
|
||||||
context->allocator = new_allocator;
|
context->allocator = new_allocator;
|
||||||
|
} else {
|
||||||
|
old_allocator = default_allocator();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~Push_Allocator () {
|
~Push_Allocator () {
|
||||||
|
if (this->context != nullptr) {
|
||||||
context->allocator = old_allocator;
|
context->allocator = old_allocator;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// #stack_trace
|
||||||
|
#define ENABLE_STACK_TRACE BUILD_DEBUG
|
||||||
|
|
||||||
|
void push_stack_trace_internal (Thread_Context* context, string file_name, string function_name, s32 line_number) {
|
||||||
|
if (context == nullptr) return;
|
||||||
|
Assert(context != nullptr);
|
||||||
|
// #no_context allocation
|
||||||
|
Stack_Trace_Node* new_node = (Stack_Trace_Node*)default_allocator_new(sizeof(Stack_Trace_Node));
|
||||||
|
|
||||||
|
new_node->data.file_name = file_name;
|
||||||
|
new_node->data.function_name = function_name;
|
||||||
|
new_node->data.line_number = line_number;
|
||||||
|
new_node->next = nullptr;
|
||||||
|
|
||||||
|
if (context->stack_trace == nullptr) {
|
||||||
|
new_node->call_depth = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
new_node->call_depth = context->stack_trace->call_depth + 1;
|
||||||
|
|
||||||
|
new_node->next = context->stack_trace;
|
||||||
|
}
|
||||||
|
|
||||||
|
context->stack_trace = new_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pop_stack_trace_internal (Thread_Context* context) {
|
||||||
|
if (context == nullptr) return;
|
||||||
|
Stack_Trace_Node* old_node = context->stack_trace;
|
||||||
|
context->stack_trace = old_node->next;
|
||||||
|
|
||||||
|
default_allocator_free(old_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ENABLE_STACK_TRACE
|
||||||
|
#define stack_trace() \
|
||||||
|
Push_Stack_Trace Concat(_push_stack_trace_guard_, __LINE__)(__FILE__, __FUNCTION__, __LINE__)
|
||||||
|
#else
|
||||||
|
#define stack_trace()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Push_Stack_Trace {
|
||||||
|
Thread_Context* context;
|
||||||
|
|
||||||
|
Push_Stack_Trace (string file_name, string function_name, s32 line_number) {
|
||||||
|
context = thread_context();
|
||||||
|
push_stack_trace_internal(context, file_name, function_name, line_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Push_Stack_Trace () {
|
||||||
|
pop_stack_trace_internal(context);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// #TODO: precede with something like: os_write_string_unsynchronized("Fatal Error!\n\nStack trace:", true);
|
||||||
|
string generate_stack_trace (Thread_Context* context) { // #no_context
|
||||||
|
String_Builder* sb = new_string_builder(Arena_Reserve::Size_64K);
|
||||||
|
|
||||||
|
Stack_Trace_Node* node = context->stack_trace;
|
||||||
|
|
||||||
|
print_to_builder(sb, "Thread index: %d, thread name: %s\n\n", context->thread_idx, context->thread_name.data);
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
append(sb, format_string("%s:%d: %s\n", node->data.file_name.data, node->data.line_number, node->data.function_name.data));
|
||||||
|
|
||||||
|
node = node->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
append(sb, "\n");
|
||||||
|
|
||||||
|
push_allocator(default_allocator());
|
||||||
|
return builder_to_string(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to use context logger here!
|
||||||
|
void print_stack_trace () {
|
||||||
|
Thread_Context* context = thread_context();
|
||||||
|
|
||||||
|
Stack_Trace_Node* node = context->stack_trace;
|
||||||
|
|
||||||
|
constexpr bool TO_STANDARD_ERROR = true;
|
||||||
|
|
||||||
|
os_write_string_unsynchronized(generate_stack_trace(context), TO_STANDARD_ERROR);
|
||||||
|
// while (node) {
|
||||||
|
// os_write_string_unsynchronized(node->data.file_name, TO_STANDARD_ERROR);
|
||||||
|
// string line_number_str = format_string(":%d: ", node->data.line_number); // maybe I shouldn't do this?
|
||||||
|
// os_write_string_unsynchronized(line_number_str, TO_STANDARD_ERROR);
|
||||||
|
// // os_write_string_unsynchronized("'", TO_STANDARD_ERROR);
|
||||||
|
// os_write_string_unsynchronized(node->data.function_name, TO_STANDARD_ERROR);
|
||||||
|
// os_write_string_unsynchronized("\n", TO_STANDARD_ERROR);
|
||||||
|
|
||||||
|
// node = node->next;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ void log_error_internal (string file_path, string function_name, s32 line_number
|
|||||||
Assert(tctx != nullptr);
|
Assert(tctx != nullptr);
|
||||||
push_arena(tctx->error_arena);
|
push_arena(tctx->error_arena);
|
||||||
|
|
||||||
String_Builder* sb = new_string_builder(Arena_Reserve::Size_64K);
|
String_Builder* sb = thread_context()->log_builder;
|
||||||
|
|
||||||
print_to_builder(sb, "%s ", error_severity(severity));
|
print_to_builder(sb, "%s ", error_severity(severity));
|
||||||
|
|
||||||
@ -93,7 +93,10 @@ void log_error_internal (string file_path, string function_name, s32 line_number
|
|||||||
|
|
||||||
append(sb, "\n");
|
append(sb, "\n");
|
||||||
|
|
||||||
string error_string = builder_to_string(sb);
|
string error_string = copy_string(string_view(sb));
|
||||||
|
|
||||||
|
reset_string_builder(sb);
|
||||||
|
|
||||||
Error* error = new_error(severity, error_string);
|
Error* error = new_error(severity, error_string);
|
||||||
// Additional information
|
// Additional information
|
||||||
error->thread_id = tctx->thread_idx;
|
error->thread_id = tctx->thread_idx;
|
||||||
|
|||||||
@ -5,23 +5,9 @@
|
|||||||
|
|
||||||
// DO NOT MERGE WITH `Arena`, we need fixed size arenas so that we can back
|
// DO NOT MERGE WITH `Arena`, we need fixed size arenas so that we can back
|
||||||
// `ArenaArray`s.
|
// `ArenaArray`s.
|
||||||
struct ExpandableArena {
|
struct ExpandableArena : Arena {
|
||||||
u8* current_point = nullptr;
|
|
||||||
u8* memory_base = nullptr;
|
|
||||||
u8* first_uncommitted_page = nullptr;
|
|
||||||
u16 alignment = CPU_REGISTER_WIDTH_BYTES;
|
|
||||||
Arena_Reserve reserve_size = Arena_Reserve::Size_64K;
|
|
||||||
Arena_Flags flags = Arena_Flags::None;
|
|
||||||
u32 initial_commit_page_count = ARENA_DEFAULT_COMMIT_PAGE_COUNT;
|
|
||||||
// Note that this downcasts to Arena*, so can be initialized in the same way.
|
|
||||||
Arena* current;
|
Arena* current;
|
||||||
Array<Arena*> next_arenas;
|
Array<Arena*> next_arenas;
|
||||||
#if BUILD_DEBUG
|
|
||||||
string info;
|
|
||||||
string file_path;
|
|
||||||
string function_name;
|
|
||||||
s32 line_number;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if BUILD_DEBUG
|
#if BUILD_DEBUG
|
||||||
|
|||||||
@ -33,6 +33,21 @@ string copy_string (string s) {
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string copy_string_no_context (string s) {
|
||||||
|
if (s.count <= 0)
|
||||||
|
return "";
|
||||||
|
string str = {};
|
||||||
|
|
||||||
|
str.count = s.count;
|
||||||
|
str.data = (u8*)default_allocator_new(s.count + 1);
|
||||||
|
|
||||||
|
memcpy(str.data, s.data, s.count);
|
||||||
|
|
||||||
|
str.data[str.count] = '\0'; // null-terminate for backwards compatibility?
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
string copy_string (char* c_string) {
|
string copy_string (char* c_string) {
|
||||||
string str = {};
|
string str = {};
|
||||||
s64 string_length = strlen(c_string);
|
s64 string_length = strlen(c_string);
|
||||||
|
|||||||
@ -77,6 +77,7 @@ bool is_valid (string s);
|
|||||||
bool is_c_string (string s);
|
bool is_c_string (string s);
|
||||||
u8* to_c_string (string s); // #allocates
|
u8* to_c_string (string s); // #allocates
|
||||||
string copy_string (string s); // #allocates, returned string is #null-terminated.
|
string copy_string (string s); // #allocates, returned string is #null-terminated.
|
||||||
|
string copy_string_no_context (string s);
|
||||||
string copy_string (char* c_string); // #allocates, returned string is #null-terminated.
|
string copy_string (char* c_string); // #allocates, returned string is #null-terminated.
|
||||||
string to_string (ArrayView<u8> str);
|
string to_string (ArrayView<u8> str);
|
||||||
ArrayView<u8> to_view (string s);
|
ArrayView<u8> to_view (string s);
|
||||||
|
|||||||
@ -136,7 +136,13 @@ internal LONG WINAPI Win32_Exception_Filter (EXCEPTION_POINTERS* exception_ptrs)
|
|||||||
for (;;) Sleep(1000);
|
for (;;) Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #TODO: Runtime assertion failed?
|
||||||
|
|
||||||
// #Exception handling code (TODO)
|
// #Exception handling code (TODO)
|
||||||
|
if (thread_context()->stack_trace) {
|
||||||
|
os_write_string_unsynchronized("\n[Win32_Exception_Filter] Stack Trace\n", true);
|
||||||
|
print_stack_trace();
|
||||||
|
}
|
||||||
|
|
||||||
ExitProcess(1);
|
ExitProcess(1);
|
||||||
|
|
||||||
@ -144,7 +150,10 @@ internal LONG WINAPI Win32_Exception_Filter (EXCEPTION_POINTERS* exception_ptrs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal void Main_Entry_Point (int argc, WCHAR **argv);
|
// internal void Main_Entry_Point (int argc, WCHAR **argv);
|
||||||
internal void Win32_Entry_Point (int argc, WCHAR **argv) {
|
internal void Win32_Entry_Point (int argc, WCHAR **argv) { stack_trace();
|
||||||
|
os_write_string_unsynchronized("Fatal Error!\n\nStack trace: ", true);
|
||||||
|
print_stack_trace();
|
||||||
|
|
||||||
// Timed_Block_Print("Win32_Entry_Point");
|
// Timed_Block_Print("Win32_Entry_Point");
|
||||||
// See: w32_entry_point_caller(); (raddebugger)
|
// See: w32_entry_point_caller(); (raddebugger)
|
||||||
SetUnhandledExceptionFilter(&Win32_Exception_Filter);
|
SetUnhandledExceptionFilter(&Win32_Exception_Filter);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ internal void Main_Entry_Point (int argc, WCHAR **argv);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal void Main_Entry_Point (int argc, WCHAR **argv) { // #entry_point
|
internal void Main_Entry_Point (int argc, WCHAR **argv) { // #entry_point: Main + Context Setup
|
||||||
// #TODO: Check if base frequency is even available.
|
// #TODO: Check if base frequency is even available.
|
||||||
u32 base_frequency = (u32)CPU_Base_Frequency();
|
u32 base_frequency = (u32)CPU_Base_Frequency();
|
||||||
set_cpu_base_frequency(base_frequency); // REQUIRED FOR TIMING MODULE! will depend on CPU
|
set_cpu_base_frequency(base_frequency); // REQUIRED FOR TIMING MODULE! will depend on CPU
|
||||||
@ -28,6 +28,8 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) { // #entry_point
|
|||||||
// before setting up the thread context!
|
// before setting up the thread context!
|
||||||
Bootstrap_Main_Thread_Context();
|
Bootstrap_Main_Thread_Context();
|
||||||
|
|
||||||
|
stack_trace(); // #stack_trace: #entry_point (first stack trace)
|
||||||
|
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
Win32_Entry_Point(argc, argv);
|
Win32_Entry_Point(argc, argv);
|
||||||
#endif
|
#endif
|
||||||
@ -37,7 +39,7 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) { // #entry_point
|
|||||||
#if BASE_RUN_TESTS
|
#if BASE_RUN_TESTS
|
||||||
run_post_setup_tests();
|
run_post_setup_tests();
|
||||||
#endif
|
#endif
|
||||||
#if BUILD_EXPLORER_APP_WIN32 // #entry_point
|
#if BUILD_EXPLORER_APP_WIN32 // #entry_point: Custom program
|
||||||
Explorer_ImGui_Application_Win32(); // #rename
|
Explorer_ImGui_Application_Win32(); // #rename
|
||||||
#endif
|
#endif
|
||||||
#if BUILD_CUSTOM_GUI
|
#if BUILD_CUSTOM_GUI
|
||||||
|
|||||||
41
src/Ex1.cpp
41
src/Ex1.cpp
@ -186,13 +186,12 @@ void Ex1_Control_Panel () { using namespace ImGui;
|
|||||||
push_allocator(temp());
|
push_allocator(temp());
|
||||||
ArrayView<OS_Drive*> drives = os_get_available_drives(); // only includes drives that are ready.
|
ArrayView<OS_Drive*> drives = os_get_available_drives(); // only includes drives that are ready.
|
||||||
|
|
||||||
|
// if (!USN_Journal_Monitoring_Ready(drives[0]) && Button("Enable USN Monitoring for all drives")) {
|
||||||
if (!USN_Journal_Monitoring_Ready(drives[0]) && Button("Enable USN Monitoring for all drives")) {
|
// Win32_Enable_USN_Journal_Monitoring(drives);
|
||||||
Win32_Enable_USN_Journal_Monitoring(drives);
|
// }
|
||||||
}
|
// if (USN_Journal_Monitoring_Ready(drives[0]) && Button("Query USN Journal")) {
|
||||||
if (USN_Journal_Monitoring_Ready(drives[0]) && Button("Query USN Journal")) {
|
// Query_USN_Journal(drives);
|
||||||
Query_USN_Journal(drives);
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
if (!all_drives_enumerated) {
|
if (!all_drives_enumerated) {
|
||||||
// Text("drive_table is valid: %d", table_is_valid(drive_table));
|
// Text("drive_table is valid: %d", table_is_valid(drive_table));
|
||||||
@ -228,9 +227,9 @@ void Ex1_Control_Panel () { using namespace ImGui;
|
|||||||
// string file_path = format_string_temp("%s_DriveData.bin", os_get_machine_name().data);
|
// string file_path = format_string_temp("%s_DriveData.bin", os_get_machine_name().data);
|
||||||
string file_path = "D:/TempSync/Filesystem_Data/MUSA-PC3_DriveData.bin";
|
string file_path = "D:/TempSync/Filesystem_Data/MUSA-PC3_DriveData.bin";
|
||||||
Text("fixed file_path: %s", file_path.data);
|
Text("fixed file_path: %s", file_path.data);
|
||||||
if (!all_drives_enumerated && file_exists(file_path)) { // #autoload
|
// if (!all_drives_enumerated && file_exists(file_path)) { // #autoload
|
||||||
Deserialize_ST_File_Enumeration(file_path);
|
// Deserialize_ST_File_Enumeration(file_path);
|
||||||
}
|
// }
|
||||||
if (drives.count > 0 && !all_drives_enumerated && file_exists(file_path) && Button("Load from file (this machine)")) {
|
if (drives.count > 0 && !all_drives_enumerated && file_exists(file_path) && Button("Load from file (this machine)")) {
|
||||||
Deserialize_ST_File_Enumeration(file_path);
|
Deserialize_ST_File_Enumeration(file_path);
|
||||||
// Deserialize_Win32_Drives(file_path);
|
// Deserialize_Win32_Drives(file_path);
|
||||||
@ -335,6 +334,28 @@ void ImGui_Debug_Panel () { using namespace ImGui;
|
|||||||
Text(t);
|
Text(t);
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
#if BUILD_DEBUG
|
||||||
|
SeparatorText("Default Allocator Allocations");
|
||||||
|
{ lock_guard(&allocator_mutex);
|
||||||
|
auto allocations = to_view(get_general_allocator_data()->allocations);
|
||||||
|
Text("%s in %lld allocations",
|
||||||
|
format_bytes(get_general_allocator_data()->total_bytes_allocated).data,
|
||||||
|
allocations.count);
|
||||||
|
for_each(a, allocations) {
|
||||||
|
Text(" [%lld] ptr: %p (size: %lld, alignment: %d)",
|
||||||
|
a, allocations[a].memory, allocations[a].size, allocations[a].alignment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SeparatorText("Arenas in Use");
|
||||||
|
{ lock_guard(&arenas_in_use_mutex);
|
||||||
|
Assert(arenas_in_use.allocated > 0);
|
||||||
|
for_each(a, arenas_in_use) {
|
||||||
|
auto arena = arenas_in_use[a];
|
||||||
|
if (!is_valid(arena)) continue;
|
||||||
|
Text("[%d], source %s:%d (%s)", a, arena->file_path.data, arena->line_number, arena->function_name.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // BUILD_DEBUG
|
||||||
SeparatorText("Child Threads");
|
SeparatorText("Child Threads");
|
||||||
SeparatorText("Errors");
|
SeparatorText("Errors");
|
||||||
ArrayView<Error*> errors = get_all_errors(thread_context());
|
ArrayView<Error*> errors = get_all_errors(thread_context());
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user