Cogs.Core
DebugFunctions.cpp
1#include "DebugFunctions.h"
2
3#include <sstream>
4
5#include <ctime>
6#include <iomanip>
7
8#include "Foundation/Logging/Logger.h"
9#include "Foundation/Platform/Unicode.h"
10
11#include "Context.h"
12
13using namespace Cogs::Core;
14
15namespace
16{
17 Cogs::Logging::Log logger = Cogs::Logging::getLogger("DebugFunctions");
18
19#ifdef _WIN32
20 std::string getTimeStamp()
21 {
22 auto currentTime = std::time(nullptr);
23
24#ifdef _WIN32
25 tm gmTime_s;
26 gmtime_s(&gmTime_s, &currentTime);
27 auto gmTime = &gmTime_s;
28#else
29 auto gmTime = std::gmtime(&currentTime);
30#endif
31
32 std::stringstream ss;
33
34 ss << std::setfill('0');
35
36 ss << 1900 + gmTime->tm_year << "-";
37 ss << std::setw(2) << gmTime->tm_mon + 1 << "-";
38 ss << std::setw(2) << gmTime->tm_mday << " ";
39
40 ss << std::setw(2) << gmTime->tm_hour << "-";
41 ss << std::setw(2) << gmTime->tm_min << "-";
42 ss << std::setw(2) << gmTime->tm_sec << " ";
43
44 return ss.str();
45 }
46#endif
47}
48
49#ifdef _WIN32
50
51void createMiniDump(BridgeContext* ctx, EXCEPTION_POINTERS * exceptionPointers)
52{
53 auto context = static_cast<Context*>(ctx);
54 LOG_ERROR(logger, "Exception caught in native code. Creating mini dump file.");
55
56 auto path = context->debug.miniDumpPath + std::string("/") + getTimeStamp() + context->debug.miniDumpName + std::string(".dmp");
57
58 auto fileHandle = ::CreateFileW(Cogs::widen(path).c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
59
60 if ((fileHandle != NULL) && (fileHandle != INVALID_HANDLE_VALUE)) {
61 MINIDUMP_EXCEPTION_INFORMATION exceptionInfo;
62
63 exceptionInfo.ThreadId = ::GetCurrentThreadId();
64 exceptionInfo.ExceptionPointers = exceptionPointers;
65 exceptionInfo.ClientPointers = FALSE;
66
67 MINIDUMP_TYPE miniDumpType = MiniDumpNormal;
68
69 auto result = ::MiniDumpWriteDump(::GetCurrentProcess(), ::GetCurrentProcessId(), fileHandle, miniDumpType, &exceptionInfo, 0, 0);
70
71 if (result) {
72 LOG_INFO(logger, "Mini dump written successfully to %s.", path.c_str());
73 }
74 else {
75 LOG_ERROR(logger, "Error writing mini dump to %s. Possible reasons are stack corruption, insufficient disk space.", path.c_str());
76 }
77
78 ::CloseHandle(fileHandle);
79 }
80 else {
81 LOG_ERROR(logger, "Error accessing mini dump file path at %s. Check for sufficient disk permissions.", path.c_str());
82 }
83}
84
85#else
86
87void createMiniDump(BridgeContext* /*context*/)
88{
89 // Noop
90}
91
92#endif
93
98void
99enableExecutionChecks(BridgeContext* ctx, CogsBool enabled)
100{
101 auto context = static_cast<Context*>(ctx);
102
103 context->debug.enableExecutionChecks = enabled;
104}
105
109void
110setMiniDumpPath(BridgeContext* ctx, const char * path)
111{
112 auto context = static_cast<Context*>(ctx);
113
114 context->debug.miniDumpPath = std::string(path);
115}
116
120void
121setMiniDumpName(BridgeContext* ctx, const char * name)
122{
123 auto context = static_cast<Context*>(ctx);
124
125 context->debug.miniDumpName = std::string(name);
126}
127
128namespace
129{
133 void accessViolationMethod()
134 {
135 LOG_DEBUG(logger, "Initiating access violation.");
136
137 int * iPtr = (int *) 0;
138 int i = *iPtr;
139
140 // Make sure i is actually accessed.
141 LOG_ERROR(logger, "Could not trigger access violation of variable %d.", i);
142 }
143}
144
148void
149triggerAccessViolation(BridgeContext* ctx)
150{
151 auto context = static_cast<Context*>(ctx);
152
153 if (context->debug.enableExecutionChecks) {
154 CHECKED(context, accessViolationMethod());
155 } else {
156 accessViolationMethod();
157 }
158}
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Log implementation class.
Definition: LogManager.h:139
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
COGSFOUNDATION_API Time currentTime()
High resolution clock time (NTP / UTC time). Returns an implementation defined absolute timestamp,...
std::string miniDumpName
Naming pattern for minidumps.
Definition: Context.h:298
bool enableExecutionChecks
If execution checks should be enabled where applicable. See the CHECKED macro.
Definition: Context.h:292
std::string miniDumpPath
Path to store minidump files at.
Definition: Context.h:295