Pol  Revision:4b29d2b
strexcpt.cpp
Go to the documentation of this file.
1 
11 #include "Program/ProgramConfig.h"
12 #include "logfacility.h"
13 #include "pol_global_config.h"
14 
15 #if defined( WINDOWS )
16 #include "Header_Windows.h"
17 #include "msjexhnd.h"
18 #include "strexcpt.h"
19 #include <stdio.h>
20 #else
21 #include "passert.h"
22 #include <execinfo.h>
23 #include <signal.h>
24 #include <unistd.h>
25 #endif
26 
27 namespace Pol
28 {
29 namespace Clib
30 {
31 #ifdef _WIN32
32 #ifndef _M_X64
33 // TODO: move the following parts to ExceptionParser.cpp
34 
35 void se_trans_func( unsigned int n, EXCEPTION_POINTERS* ex )
36 {
37  fmt::Writer tmp;
38  tmp << "Structured Exception Detected: 0x" << fmt::hex( n ) << "\n"
39  << "ExceptionRecord:\n"
40  << " Exception Code: 0x" << fmt::hex( ex->ExceptionRecord->ExceptionCode ) << "\n"
41  << " Exception Flags: 0x" << fmt::hex( ex->ExceptionRecord->ExceptionFlags ) << "\n"
42  << " Exception Record: 0x"
43  << fmt::hex(
44  (long long)( reinterpret_cast<const void*>( ex->ExceptionRecord->ExceptionRecord ) ) )
45  << "\n"
46  << " Exception Address: 0x"
47  << fmt::hex(
48  (long long)( reinterpret_cast<const void*>( ex->ExceptionRecord->ExceptionAddress ) ) )
49  << "\n"
50  << " NumberParameters: 0x" << fmt::hex( ex->ExceptionRecord->NumberParameters ) << "\n";
51 
52  if ( ex->ExceptionRecord->NumberParameters )
53  {
54  tmp << " Exception Information:";
55  for ( DWORD i = 0; i < ex->ExceptionRecord->NumberParameters; i++ )
56  {
57  fmt::Writer _tmp;
58  _tmp.Format( "{}{:#X}" ) << ( ( ( i & 7 ) == 0 ) ? "\n "
59  : " " ) // print newline every 8 numbers
60  << ex->ExceptionRecord->ExceptionInformation[i];
61  tmp << _tmp.str();
62  }
63  tmp << "\n";
64  }
65  POLLOG_INFO << tmp.str();
66 
67 
68  POLLOG_INFO << "ContextRecord:\n"
69  << " ContextFlags: 0x" << fmt::hex( ex->ContextRecord->ContextFlags ) << "\n";
70  if ( ex->ContextRecord->ContextFlags & CONTEXT_DEBUG_REGISTERS )
71  {
72  POLLOG_INFO << " CONTEXT_DEBUG_REGISTERS:\n"
73  << " Dr0: 0x" << fmt::hex( ex->ContextRecord->Dr0 ) << "\n"
74  << " Dr1: 0x" << fmt::hex( ex->ContextRecord->Dr1 ) << "\n"
75  << " Dr2: 0x" << fmt::hex( ex->ContextRecord->Dr2 ) << "\n"
76  << " Dr3: 0x" << fmt::hex( ex->ContextRecord->Dr3 ) << "\n"
77  << " Dr6: 0x" << fmt::hex( ex->ContextRecord->Dr6 ) << "\n"
78  << " Dr7: 0x" << fmt::hex( ex->ContextRecord->Dr7 ) << "\n";
79  }
80  if ( ex->ContextRecord->ContextFlags & CONTEXT_SEGMENTS )
81  {
82  POLLOG_INFO << " CONTEXT_SEGMENTS:\n"
83  << " SegGs: 0x" << fmt::hex( ex->ContextRecord->SegGs ) << "\n"
84  << " SegFs: 0x" << fmt::hex( ex->ContextRecord->SegFs ) << "\n"
85  << " SegEs: 0x" << fmt::hex( ex->ContextRecord->SegEs ) << "\n"
86  << " SegDs: 0x" << fmt::hex( ex->ContextRecord->SegDs ) << "\n";
87  }
88  if ( ex->ContextRecord->ContextFlags & CONTEXT_INTEGER )
89  {
90  POLLOG_INFO << " CONTEXT_INTEGER:\n"
91  << " Edi: 0x" << fmt::hex( ex->ContextRecord->Edi ) << "\n"
92  << " Esi: 0x" << fmt::hex( ex->ContextRecord->Esi ) << "\n"
93  << " Ebx: 0x" << fmt::hex( ex->ContextRecord->Ebx ) << "\n"
94  << " Edx: 0x" << fmt::hex( ex->ContextRecord->Edx ) << "\n"
95  << " Ecx: 0x" << fmt::hex( ex->ContextRecord->Ecx ) << "\n"
96  << " Eax: 0x" << fmt::hex( ex->ContextRecord->Eax ) << "\n";
97  }
98  if ( ex->ContextRecord->ContextFlags & CONTEXT_CONTROL )
99  {
100  POLLOG_INFO << " CONTEXT_CONTROL:\n"
101  << " Ebp: 0x" << fmt::hex( ex->ContextRecord->Ebp ) << "\n"
102  << " Eip: 0x" << fmt::hex( ex->ContextRecord->Eip ) << "\n"
103  << " SegCs: 0x" << fmt::hex( ex->ContextRecord->SegCs ) << "\n"
104  << " EFlags: 0x" << fmt::hex( ex->ContextRecord->EFlags ) << "\n"
105  << " Esp: 0x" << fmt::hex( ex->ContextRecord->Esp ) << "\n"
106  << " SegSs: 0x" << fmt::hex( ex->ContextRecord->SegSs ) << "\n";
107 
108  POLLOG_INFO << " Stack Backtrace:\n";
109  // int frames = 3;
110  DWORD* ebp = (DWORD*)ex->ContextRecord->Ebp;
111  DWORD eip = ex->ContextRecord->Eip;
112  DWORD* new_ebp;
113  DWORD new_eip;
114 
115 
116  fmt::Writer tmp;
117  tmp << " EIP RETADDR\n";
118  int levelsleft = 100;
119  while ( ebp && levelsleft-- )
120  {
121  tmp << " 0x" << fmt::hex( eip );
122 
123  if ( !IsBadReadPtr( ebp, sizeof *ebp ) )
124  {
125  new_ebp = (DWORD*)*ebp;
126  }
127  else
128  {
129  tmp << "[Can't read stack!]\n";
130  break;
131  }
132  if ( !IsBadReadPtr( ebp + 1, sizeof *ebp ) )
133  {
134  tmp << " 0x" << fmt::hex( *( ebp + 1 ) );
135  new_eip = *( ebp + 1 );
136  }
137  else
138  {
139  tmp << "[Can't read stack!]\n";
140  break;
141  }
142 
143  ebp = new_ebp;
144  eip = new_eip;
145  tmp << "\n";
146  }
147  POLLOG_INFO << tmp.str();
148  }
149 
150  if ( n == EXCEPTION_ACCESS_VIOLATION )
151  {
152  throw access_violation();
153  }
154  else
155  {
156  throw structured_exception( n );
157  }
158 }
159 #endif
160 
161 static bool in_ex_handler = false;
162 void alt_se_trans_func( unsigned int u, _EXCEPTION_POINTERS* pExp )
163 {
164  INFO_PRINT << "In trans_func.\n";
165  if ( in_ex_handler )
166  {
167  POLLOG_INFO << "recursive structured exception\n";
168  }
169  else
170  {
171  in_ex_handler = true;
172  POLLOG_INFO.Format( "Structured exception in {} compiled on {} at {}\n" )
174 
176  in_ex_handler = false;
177  }
178  throw structured_exception( u );
179 }
180 
182 {
183  if ( !IsDebuggerPresent() )
184  {
185  _set_se_translator( alt_se_trans_func );
186  }
187 }
188 
189 #endif
190 }
191 }
#define POLLOG_INFO
Definition: logfacility.h:213
static LONG WINAPI MSJUnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo)
Definition: msjexhnd.cpp:97
typedef DWORD(WINAPI *__SymGetOptions)(VOID)
void InstallOldStructuredExceptionHandler(void)
#define INFO_PRINT
Definition: logfacility.h:223
Definition: berror.cpp:12
static std::string build_datetime()