Skip to content

Commit c70e779

Browse files
committed
fix(Log): Crash when chrono::current_zone fails
1 parent b0d0b78 commit c70e779

File tree

8 files changed

+79
-87
lines changed

8 files changed

+79
-87
lines changed

UE4SS/src/CrashDumper.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <polyhook2/PE/IatHook.hpp>
99
#include <dbghelp.h>
1010
#include <Helpers/SysError.hpp>
11+
#include <Helpers/Time.hpp>
1112
#include <String/StringType.hpp>
1213

1314
namespace fs = std::filesystem;
@@ -25,25 +26,7 @@ namespace RC
2526

2627
LONG WINAPI ExceptionHandler(_EXCEPTION_POINTERS* exception_pointers)
2728
{
28-
StringType dump_path{};
29-
bool use_local_time = true;
30-
#ifdef _WIN32
31-
if (auto module = GetModuleHandleW(L"ntdll.dll"); module && GetProcAddress(module, "wine_get_version"))
32-
{
33-
use_local_time = false;
34-
}
35-
#endif
36-
if (use_local_time)
37-
{
38-
static const auto timezone = std::chrono::current_zone();
39-
const auto now = time_point_cast<seconds>(timezone->to_local(system_clock::now()));
40-
dump_path = fmt::format(STR("{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp"), StringType{UE4SSProgram::get_program().get_working_directory()}, now);
41-
}
42-
else
43-
{
44-
const auto now = time_point_cast<seconds>(system_clock::now());
45-
dump_path = fmt::format(STR("{}\\crash_{:%Y_%m_%d_%H_%M_%S}.dmp"), StringType{UE4SSProgram::get_program().get_working_directory()}, now);
46-
}
29+
StringType dump_path = fmt::format(STR("{}\\crash_{}.dmp"), StringType{UE4SSProgram::get_program().get_working_directory()}, get_now_as_string(STR("{:%Y_%m_%d_%H_%M_%S}")));
4730

4831
const HANDLE file =
4932
CreateFileW(FromCharTypePtr<wchar_t>(dump_path.c_str()), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

UE4SS/src/UE4SSProgram.cpp

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <Helpers/Format.hpp>
2424
#include <Helpers/Integer.hpp>
2525
#include <Helpers/String.hpp>
26+
#include <Helpers/Time.hpp>
2627
#include <IniParser/Ini.hpp>
2728
#include <LuaLibrary.hpp>
2829
#include <LuaType/LuaCustomProperty.hpp>
@@ -213,26 +214,7 @@ namespace RC
213214
{
214215
m_console_device = &Output::set_default_devices<Output::ConsoleDevice>();
215216
m_console_device->set_formatter([](File::StringViewType string) -> File::StringType {
216-
bool use_local_time = true;
217-
#ifdef _WIN32
218-
if (auto module = GetModuleHandleW(L"ntdll.dll"); module && GetProcAddress(module, "wine_get_version"))
219-
{
220-
use_local_time = false;
221-
}
222-
#endif
223-
if (use_local_time)
224-
{
225-
static const auto timezone = std::chrono::current_zone();
226-
return fmt::format(STR("[{}] {}"),
227-
fmt::format(STR("{:%X}"),
228-
std::chrono::time_point_cast<std::chrono::system_clock::duration>(
229-
timezone->to_local(std::chrono::system_clock::now()))),
230-
string);
231-
}
232-
else
233-
{
234-
return fmt::format(STR("[{}] {}"), fmt::format(STR("{:%X}"), std::chrono::system_clock::now()), string);
235-
}
217+
return fmt::format(STR("[{}] {}"), get_now_as_string(STR("{:%X}")), string);
236218
});
237219
if (settings_manager.Debug.DebugConsoleVisible)
238220
{
@@ -279,7 +261,14 @@ namespace RC
279261
#endif
280262
if (use_local_time)
281263
{
282-
Output::send(STR("Timezone: {}\n"), ensure_str(std::chrono::current_zone()->name()));
264+
try
265+
{
266+
Output::send(STR("Timezone: {}\n"), ensure_str(std::chrono::current_zone()->name()));
267+
}
268+
catch (std::runtime_error&)
269+
{
270+
Output::send(STR("Timezone: UTC (local disabled due to lack of support (chrono::current_zone() failed))\n"));
271+
}
283272
}
284273
else
285274
{
@@ -523,26 +512,7 @@ namespace RC
523512
m_debug_console_device = &Output::set_default_devices<Output::DebugConsoleDevice>();
524513
Output::set_default_log_level<LogLevel::Normal>();
525514
m_debug_console_device->set_formatter([](File::StringViewType string) -> File::StringType {
526-
bool use_local_time = true;
527-
#ifdef _WIN32
528-
if (auto module = GetModuleHandleW(L"ntdll.dll"); module && GetProcAddress(module, "wine_get_version"))
529-
{
530-
use_local_time = false;
531-
}
532-
#endif
533-
if (use_local_time)
534-
{
535-
static const auto timezone = std::chrono::current_zone();
536-
return fmt::format(STR("[{}] {}"),
537-
fmt::format(STR("{:%X}"),
538-
std::chrono::time_point_cast<std::chrono::system_clock::duration>(
539-
timezone->to_local(std::chrono::system_clock::now()))),
540-
string);
541-
}
542-
else
543-
{
544-
return fmt::format(STR("[{}] {}"), fmt::format(STR("{:%X}"), std::chrono::system_clock::now()), string);
545-
}
515+
return fmt::format(STR("[{}] {}"), get_now_as_string(STR("{:%X}")), string);
546516
});
547517

548518
if (AllocConsole())

deps/first/DynamicOutput/include/DynamicOutput/OutputDevice.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ namespace RC::Output
6868
auto set_formatter(Formatter new_formatter) -> void;
6969

7070
protected:
71-
auto static get_now_as_string() -> const File::StringType;
7271
auto static default_format_string(File::StringViewType) -> File::StringType;
7372
};
7473
} // namespace RC::Output

deps/first/DynamicOutput/src/OutputDevice.cpp

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <fmt/xchar.h>
44
#include <fmt/chrono.h>
55
#include <DynamicOutput/OutputDevice.hpp>
6+
#include <Helpers/Time.hpp>
67

78
#if _WIN32
89
#define NOMINMAX
@@ -31,32 +32,8 @@ namespace RC::Output
3132
m_formatter = new_formatter;
3233
}
3334

34-
auto OutputDevice::get_now_as_string() -> const File::StringType
35-
{
36-
File::StringType when_as_string{};
37-
bool use_local_time = true;
38-
#ifdef _WIN32
39-
if (auto module = GetModuleHandleW(L"ntdll.dll"); module && GetProcAddress(module, "wine_get_version"))
40-
{
41-
use_local_time = false;
42-
}
43-
#endif
44-
if (use_local_time)
45-
{
46-
static const auto timezone = std::chrono::current_zone();
47-
auto now = std::chrono::time_point_cast<std::chrono::system_clock::duration>(timezone->to_local(std::chrono::system_clock::now()));
48-
when_as_string = fmt::format(STR("{:%Y-%m-%d %X}"), now);
49-
}
50-
else
51-
{
52-
auto now = std::chrono::system_clock::now();
53-
when_as_string = fmt::format(STR("{:%Y-%m-%d %X}"), now);
54-
}
55-
return when_as_string;
56-
}
57-
5835
auto OutputDevice::default_format_string(File::StringViewType string_to_format) -> File::StringType
5936
{
60-
return fmt::format(STR("[{}] {}"), get_now_as_string(), string_to_format);
37+
return fmt::format(STR("[{}] {}"), get_now_as_string(STR("{:%Y-%m-%d %X}")), string_to_format);
6138
}
6239
} // namespace RC::Output

deps/first/Helpers/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ option(UE4SS_${TARGET}_BUILD_SHARED "Build as a shared lib" OFF)
77
set(${TARGET}_Sources
88
"${CMAKE_CURRENT_SOURCE_DIR}/src/Casting.cpp"
99
"${CMAKE_CURRENT_SOURCE_DIR}/src/SysError.cpp"
10+
"${CMAKE_CURRENT_SOURCE_DIR}/src/Time.cpp"
1011
)
1112

1213
string(REGEX REPLACE "(.)([A-Z])" "\\1_\\2" MODULE_NAME ${TARGET})
@@ -29,7 +30,7 @@ target_compile_definitions(${TARGET} PRIVATE
2930
RC_${MODULE_NAME}_BUILD_STATIC>)
3031

3132
target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
32-
target_link_libraries(${TARGET} PUBLIC String)
33+
target_link_libraries(${TARGET} PUBLIC String fmt)
3334

3435
# Make headers visible in the IDE
3536
# Uses make_headers_visible() from cmake/modules/IDEVisibility.cmake
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#pragma once
2+
3+
#include <String/StringType.hpp>
4+
5+
namespace RC
6+
{
7+
auto get_now_as_string(StringViewType format = STR("{:%Y_%m_%d_%H_%M_%S}")) -> StringType;
8+
} // namespace RC

deps/first/Helpers/src/Time.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <chrono>
2+
3+
#include <Helpers/Time.hpp>
4+
#include <fmt/xchar.h>
5+
#include <fmt/chrono.h>
6+
7+
#if _WIN32
8+
#define NOMINMAX
9+
#include <Windows.h>
10+
#ifdef TEXT
11+
#undef TEXT
12+
#endif
13+
#endif
14+
15+
#if RC_IS_ANSI == 1
16+
#define RC_STD_MAKE_FORMAT_ARGS fmt::make_format_args
17+
#else
18+
#define RC_STD_MAKE_FORMAT_ARGS fmt::make_format_args<fmt::buffered_context<CharType>>
19+
#endif
20+
21+
namespace RC
22+
{
23+
auto get_now_as_string(StringViewType format) -> StringType
24+
{
25+
bool use_local_time = true;
26+
#ifdef _WIN32
27+
if (auto module = GetModuleHandleW(L"ntdll.dll"); module && GetProcAddress(module, "wine_get_version"))
28+
{
29+
use_local_time = false;
30+
}
31+
#endif
32+
33+
if (use_local_time)
34+
{
35+
try
36+
{
37+
static const auto timezone = std::chrono::current_zone();
38+
const auto now = std::chrono::time_point_cast<std::chrono::system_clock::duration>(timezone->to_local(std::chrono::system_clock::now()));
39+
return fmt::vformat(fmt::detail::to_string_view(format), RC_STD_MAKE_FORMAT_ARGS(now));
40+
}
41+
catch (std::runtime_error&)
42+
{
43+
const auto now = std::chrono::system_clock::now();
44+
return fmt::vformat(fmt::detail::to_string_view(format), RC_STD_MAKE_FORMAT_ARGS(now));
45+
}
46+
}
47+
else
48+
{
49+
const auto now = std::chrono::system_clock::now();
50+
return fmt::vformat(fmt::detail::to_string_view(format), RC_STD_MAKE_FORMAT_ARGS(now));
51+
}
52+
}
53+
} // namespace RC

deps/first/Helpers/xmake.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ target(projectName)
77
add_rules("ue4ss.dependency")
88

99
add_deps("String")
10+
add_packages("fmt")
1011

1112
add_includedirs("include", { public = true })
1213
add_headerfiles("include/**.hpp")

0 commit comments

Comments
 (0)