| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
| 2 | 2 |
| 3 #include "PluginDebug.h" | 3 #include "PluginDebug.h" |
| 4 #include "PluginMutex.h" | 4 #include "PluginMutex.h" |
| 5 #include "PluginSettings.h" | 5 #include "PluginSettings.h" |
| 6 | 6 |
| 7 #include <iomanip> | |
| 7 | 8 |
| 8 class CPluginDebugLock : public CPluginMutex | 9 class CPluginDebugLock : public CPluginMutex |
| 9 { | 10 { |
| 10 | 11 |
| 11 private: | 12 private: |
| 12 | 13 |
| 13 static CComAutoCriticalSection s_criticalSectionDebugLock; | 14 static CComAutoCriticalSection s_criticalSectionDebugLock; |
| 14 | 15 |
| 15 public: | 16 public: |
| 16 | 17 |
| 17 CPluginDebugLock() : CPluginMutex("DebugFile", PLUGIN_ERROR_MUTEX_DEBUG_FILE) | 18 CPluginDebugLock() : CPluginMutex( L"DebugFile", PLUGIN_ERROR_MUTEX_DEBUG_FILE ) |
| 18 { | 19 { |
| 19 s_criticalSectionDebugLock.Lock(); | 20 s_criticalSectionDebugLock.Lock(); |
| 20 } | 21 } |
| 21 | 22 |
| 22 ~CPluginDebugLock() | 23 ~CPluginDebugLock() |
| 23 { | 24 { |
| 24 s_criticalSectionDebugLock.Unlock(); | 25 s_criticalSectionDebugLock.Unlock(); |
| 25 } | 26 } |
| 26 }; | 27 }; |
| 27 | 28 |
| 28 CComAutoCriticalSection CPluginDebugLock::s_criticalSectionDebugLock; | 29 CComAutoCriticalSection CPluginDebugLock::s_criticalSectionDebugLock; |
| 29 | 30 |
| 31 std::wstring ABP::debug::widen( std::string s ) | |
| 32 { | |
| 33 return std::wstring( s.begin(), s.end() ); | |
|
sergei
2014/07/08 11:58:34
Please, get acquainted with the concept of utf-8.
Eric
2014/07/08 17:46:37
I am fully acquainted with UTF-8.
This isn't a fu
| |
| 34 } | |
| 35 | |
| 36 std::string ABP::debug::narrow( std::wstring s ) | |
| 37 { | |
| 38 return std::string( s.begin(), s.end() ); | |
| 39 } | |
| 40 | |
| 41 void ABP::debug::truncate_source( std::wstring & src ) | |
| 42 { | |
| 43 size_t len = src.length(); | |
| 44 if ( len <= 100 ) | |
| 45 { | |
| 46 return; | |
| 47 } | |
| 48 // Preserve [0..67) length=67 | |
| 49 // Replace [67..70) with ellipsis length=3 | |
| 50 // Erase positions [70..len-30) length=len-100 | |
| 51 // Preverse as shifted [len-30,len) length=30 | |
| 52 src.replace( 67, 3, L"..." ); | |
| 53 src.erase( 70, len - 100 ); | |
| 54 } | |
| 55 | |
| 56 namespace { | |
| 57 /** | |
| 58 * Output a timestamp into a stream. | |
| 59 */ | |
| 60 void add_timestamp( std::wostream & ss ) | |
| 61 { | |
| 62 SYSTEMTIME st; | |
| 63 ::GetSystemTime(&st); | |
| 64 | |
| 65 ss << std::setfill(L'0'); | |
| 66 ss << std::setw(2) << st.wHour << ':'; | |
| 67 ss << std::setw(2) << st.wMinute << ':'; | |
| 68 ss << std::setw(2) << st.wSecond << '.'; | |
| 69 ss << std::setw(3) << st.wMilliseconds << " - "; | |
| 70 } | |
| 71 } | |
| 30 | 72 |
| 31 #ifdef ENABLE_DEBUG_INFO | 73 #ifdef ENABLE_DEBUG_INFO |
| 32 | 74 |
| 33 void CPluginDebug::Debug(const CString& text, DWORD dwProcessId, DWORD dwThreadI d) | 75 void CPluginDebug::Debug(const std::wstring & text, DWORD dwProcessId, DWORD dwT hreadId) |
| 76 { | |
| 77 std::wstring t[1]; | |
| 78 t[0] = text; | |
| 79 CPluginDebug::Debug( t, dwProcessId, dwThreadId ); | |
| 80 } | |
| 81 | |
| 82 void CPluginDebug::Debug(const std::wstring lines[], size_t n_lines, DWORD dwPro cessId, DWORD dwThreadId) | |
| 34 { | 83 { |
| 35 #ifdef USE_CONSOLE | 84 #ifdef USE_CONSOLE |
| 36 CONSOLE(CT2A(text.GetString(), CP_UTF8)); | 85 // CT2A is a shared MFC/ATL macro, so we can leave it in for now |
| 86 CONSOLE(CT2A(text.c_str(), CP_UTF8)); | |
| 37 #endif | 87 #endif |
| 38 | 88 |
| 39 if (CPluginSettings::HasInstance()) | 89 if (CPluginSettings::HasInstance()) |
| 40 { | 90 { |
| 41 #ifdef ENABLE_DEBUG_SPLIT_FILE | 91 #ifdef ENABLE_DEBUG_SPLIT_FILE |
| 42 CPluginSettings* settings = CPluginSettings::GetInstance(); | 92 std::wostringstream logfile_name; |
| 43 | 93 logfile_name << L"debug_tab"; |
| 44 bool isWorkingThread = settings->IsWorkingThread(dwThreadId); | 94 logfile_name << ::GetCurrentProcessId(); |
| 45 | 95 logfile_name << ( ( CPluginSettings::GetInstance()->IsWorkingThread(dwThread Id) ) ? L"_thread.txt" : L"_ui.txt" ); |
| 46 CString processor; | |
| 47 wchar_t tmp[10]; | |
| 48 _itow_s(::GetCurrentProcessId(), tmp, 10); | |
| 49 if (isWorkingThread) | |
| 50 processor = L"tab" + CString(tmp) + L"_thread"; | |
| 51 else | |
| 52 processor = L"tab" + CString(tmp) + L"_ui"; | |
| 53 #else | 96 #else |
| 54 if (dwProcessId == 0) | 97 if (dwProcessId == 0) |
| 55 { | 98 { |
| 56 dwProcessId = ::GetCurrentProcessId(); | 99 dwProcessId = ::GetCurrentProcessId(); |
| 57 } | 100 } |
| 58 if (dwThreadId == 0) | 101 if (dwThreadId == 0) |
| 59 { | 102 { |
| 60 dwThreadId = ::GetCurrentThreadId(); | 103 dwThreadId = ::GetCurrentThreadId(); |
| 61 } | 104 } |
| 105 std::wstring logfile_name = L"debug.txt"; | |
| 106 #endif | |
| 62 | 107 |
| 63 CStringA processInfo; | 108 std::wostringstream prefix ; |
| 64 processInfo.Format("%4.4u.%4.4u - ", dwProcessId, dwThreadId); | 109 add_timestamp( prefix ); |
| 110 #ifndef ENABLE_DEBUG_SPLIT_FILE | |
| 111 prefix << std::setw(4) << dwProcessId << '.'; | |
| 112 prefix << std::setw(4) << dwThreadId << " - "; | |
| 65 #endif | 113 #endif |
| 66 SYSTEMTIME st; | |
| 67 ::GetSystemTime(&st); | |
| 68 | |
| 69 CStringA sysTime; | |
| 70 sysTime.Format("%2.2d:%2.2d:%2.2d.%3.3d - ", st.wHour, st.wMinute, st.wSecon d, st.wMilliseconds); | |
| 71 | 114 |
| 72 CPluginDebugLock lock; | 115 CPluginDebugLock lock; |
| 73 if (lock.IsLocked()) | 116 if (lock.IsLocked()) |
| 74 { | 117 { |
| 75 std::ofstream debugFile; | 118 std::wofstream debugFile; |
| 76 | 119 debugFile.open(CPluginSettings::GetDataPath(logfile_name.str()), std::ios: :app); |
| 77 #ifdef ENABLE_DEBUG_SPLIT_FILE | 120 for ( size_t i = 0 ; i < n_lines ; ++i ) |
| 78 debugFile.open(CPluginSettings::GetDataPath(L"debug_" + processor + L".txt "), std::ios::app); | |
| 79 #else | |
| 80 debugFile.open(CPluginSettings::GetDataPath(L"debug.txt"), std::ios::app); | |
| 81 #endif | |
| 82 int pos = 0; | |
| 83 CStringA line = text.Tokenize(L"\n\r", pos); | |
| 84 | |
| 85 while (pos >= 0) | |
| 86 { | 121 { |
| 87 debugFile.write(sysTime.GetBuffer(), sysTime.GetLength()); | 122 debugFile << prefix.str() << lines[i] << std::endl; |
| 88 #ifndef ENABLE_DEBUG_SPLIT_FILE | |
| 89 debugFile.write(processInfo.GetBuffer(), processInfo.GetLength()); | |
| 90 #endif | |
| 91 debugFile.write(line.GetBuffer(), line.GetLength()); | |
| 92 debugFile.write("\n", 1); | |
| 93 | |
| 94 line = text.Tokenize(L"\n\r", pos); | |
| 95 } | 123 } |
| 96 | 124 debugFile.close(); |
| 97 debugFile.flush(); | |
| 98 } | 125 } |
| 99 } | 126 } |
| 100 } | 127 } |
| 101 | 128 |
| 102 void CPluginDebug::DebugClear() | 129 void CPluginDebug::DebugClear() |
| 103 { | 130 { |
| 104 CPluginDebugLock lock; | 131 CPluginDebugLock lock; |
| 105 if (lock.IsLocked()) | 132 if (lock.IsLocked()) |
| 106 { | 133 { |
| 107 ::DeleteFile(CPluginSettings::GetDataPath(L"debug.txt")); | 134 ::DeleteFile(CPluginSettings::GetDataPath(L"debug.txt").c_str()); |
| 108 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_main_ui.txt")); | 135 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_main_ui.txt").c_str()); |
| 109 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_main_thread.txt")); | 136 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_main_thread.txt").c_str()) ; |
| 110 | 137 |
| 138 // DEFECT: This needs to use FindFirst/FindNext, since the numbers in the fi le names are process ID's. | |
| 111 for (int i = 1; i <= 10; i++) | 139 for (int i = 1; i <= 10; i++) |
| 112 { | 140 { |
| 113 CString x; | 141 std::wostringstream s; |
| 114 x.Format(L"%d", i); | 142 s << L"debug_tab" << i ; |
| 115 | 143 ::DeleteFile(CPluginSettings::GetDataPath(s.str() + L"_ui.txt").c_str()); |
| 116 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_tab" + x + L"_ui.txt")); | 144 ::DeleteFile(CPluginSettings::GetDataPath(s.str() + L"_thread.txt").c_str( )); |
| 117 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_tab" + x + L"_thread.txt ")); | |
| 118 } | 145 } |
| 119 } | 146 } |
| 120 } | 147 } |
| 121 | 148 |
| 122 #endif | 149 #endif |
| 123 | 150 |
| 124 #if (defined ENABLE_DEBUG_INFO || defined ENABLE_DEBUG_SELFTEST) | 151 #if (defined ENABLE_DEBUG_INFO || defined ENABLE_DEBUG_SELFTEST) |
| 125 | 152 |
| 126 void CPluginDebug::DebugError(const CString& error) | 153 void CPluginDebug::DebugError(std::string error) |
| 127 { | 154 { |
| 155 /* | |
| 156 * Convert the narrow string to a wide one. | |
| 157 * This method assumes that the original string is plain ASCII, with no multib yte sequences (such as UTF-8). | |
| 158 */ | |
| 159 std::wstring werror (error.begin(), error.end()); | |
| 160 | |
| 128 #ifdef ENABLE_DEBUG_ERROR | 161 #ifdef ENABLE_DEBUG_ERROR |
| 129 Debug(error); | 162 Debug(werror); |
| 130 #endif | 163 #endif |
| 131 | 164 |
| 132 DEBUG_SELFTEST("************************************************************** ******************\n" + error + "\n********************************************* ***********************************") | 165 std::wstring t[] = { |
| 166 L"************************************************************************** ******", | |
| 167 werror, | |
| 168 L"************************************************************************** ******", | |
| 169 }; | |
| 170 DEBUG_SELFTEST( t ); | |
| 133 } | 171 } |
| 134 | 172 |
| 135 void CPluginDebug::DebugErrorCode(DWORD errorCode, const CString& error, DWORD d wProcessId, DWORD dwThreadId) | 173 void CPluginDebug::DebugErrorCode(DWORD errorCode, const std::wstring & error, D WORD dwProcessId, DWORD dwThreadId) |
| 136 { | 174 { |
| 137 CString errorCodeText; | 175 std::wostringstream line; |
| 138 errorCodeText.Format(L"%u (0x%8.8x)", errorCode, errorCode); | 176 line << error << L". error="; |
| 139 | 177 line << errorCode << L" (0x"; |
| 140 CString finalError = error + L". error=" + errorCodeText; | 178 line << std::setw( 8 ) << std::setfill( L'0' ) << std::hex << errorCode << L") "; |
| 141 | |
| 142 #ifdef ENABLE_DEBUG_ERROR | 179 #ifdef ENABLE_DEBUG_ERROR |
| 143 Debug(finalError, dwProcessId, dwThreadId); | 180 Debug( line.str(), dwProcessId, dwThreadId ); |
| 144 #endif | 181 #endif |
| 145 | 182 |
| 146 DEBUG_SELFTEST(L"************************************************************* *******************\n" + finalError + "\n*************************************** *****************************************") | 183 std::wstring t[] = { |
| 184 L"************************************************************************** ******", | |
| 185 line.str(), | |
| 186 L"************************************************************************** ******" | |
| 187 }; | |
| 188 DEBUG_SELFTEST( t ); | |
| 147 } | 189 } |
| 148 | 190 |
| 149 #endif | 191 #endif |
| 150 | 192 |
| 151 // ============================================================================ | 193 // ============================================================================ |
| 152 // Debug result | 194 // Debug result |
| 153 // ============================================================================ | 195 // ============================================================================ |
| 154 | 196 |
| 155 #ifdef ENABLE_DEBUG_RESULT | 197 #ifdef ENABLE_DEBUG_RESULT |
| 156 | 198 |
| 157 void CPluginDebug::DebugResult(const CString& text) | 199 void CPluginDebug::DebugResult(const std::wstring & text) |
| 158 { | 200 { |
| 159 SYSTEMTIME st; | |
| 160 ::GetSystemTime(&st); | |
| 161 | |
| 162 CStringA sysTime; | |
| 163 sysTime.Format("%2.2d:%2.2d:%2.2d.%3.3d - ", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds); | |
| 164 | |
| 165 CStringA textA = text; | |
| 166 | |
| 167 CPluginDebugLock lock; | 201 CPluginDebugLock lock; |
| 168 if (lock.IsLocked()) | 202 if (lock.IsLocked()) |
| 169 { | 203 { |
| 170 std::ofstream debugFile; | 204 std::wofstream debugFile; |
| 171 | 205 debugFile.open(CPluginSettings::GetDataPath(L"debug_result.txt"), std::ios:: app); |
| 172 debugFile.open(CPluginSettings::GetDataPath("debug_result.txt"), std::ios::a pp); | 206 add_timestamp( debugFile ); |
| 173 debugFile.write(sysTime.GetBuffer(), sysTime.GetLength()); | 207 debugFile << text << std::endl; |
| 174 debugFile.write(LPCSTR(textA), textA.GetLength()); | |
| 175 debugFile.write("\n", 1); | |
| 176 debugFile.flush(); | 208 debugFile.flush(); |
| 209 debugFile.close(); | |
| 177 } | 210 } |
| 178 } | 211 } |
| 179 | 212 |
| 180 void CPluginDebug::DebugResultDomain(const CString& domain) | 213 void CPluginDebug::DebugResultDomain(const std::wstring & domain) |
| 181 { | 214 { |
| 182 DebugResult(L"================================================================ ================================================================================ ==========================================="); | 215 DebugResult(L"================================================================ ================================================================================ ==========================================="); |
| 183 DebugResult(domain); | 216 DebugResult(domain); |
| 184 DebugResult(L"================================================================ ================================================================================ ==========================================="); | 217 DebugResult(L"================================================================ ================================================================================ ==========================================="); |
| 185 } | 218 } |
| 186 | 219 |
| 187 | 220 |
| 188 void CPluginDebug::DebugResultBlocking(const CString& type, const CString& src, const CString& domain) | 221 void CPluginDebug::DebugResultBlocking(const std::wstring & type, const std::wst ring & src, const std::wstring & domain) |
| 189 { | 222 { |
| 190 CString srcTrunc = src; | 223 std::wstring src_truncated( src ); |
| 191 if (srcTrunc.GetLength() > 100) | 224 ABP::debug::truncate_source( src_truncated ); |
| 192 { | |
| 193 srcTrunc = src.Left(67) + L"..." + src.Right(30); | |
| 194 } | |
| 195 | 225 |
| 196 CString blocking; | 226 std::wostringstream line; |
| 197 blocking.Format(L"Blocked %-12s %-20s %s", type, domain.IsEmpty()? L"-" : d omain, srcTrunc); | 227 line << L"Blocked "; |
| 228 line << std::setw( 12 ) << std::left << type << L" "; | |
| 229 line << std::setw( 20 ) << std::left << ( domain.empty() ? L"-" : domain ) << L" "; | |
| 230 line << src_truncated; | |
| 198 | 231 |
| 199 DebugResult(blocking); | 232 DebugResult( line.str() ); |
| 200 } | 233 } |
| 201 | 234 |
| 202 | 235 |
| 203 void CPluginDebug::DebugResultHiding(const CString& tag, const CString& src, con st CString& filter) | 236 void CPluginDebug::DebugResultHiding(const std::wstring & tag, const std::wstrin g & src, const std::wstring & filter) |
| 204 { | 237 { |
| 205 CString srcTrunc = src; | 238 std::wstring src_truncated( src ); |
| 206 if (srcTrunc.GetLength() > 100) | 239 ABP::debug::truncate_source( src_truncated ); |
| 207 { | |
| 208 srcTrunc = src.Left(67) + L"..." + src.Right(30); | |
| 209 } | |
| 210 | 240 |
| 211 CString blocking; | 241 std::wostringstream line; |
| 212 blocking.Format(L"Hidden %-12s - %s %s", tag, srcTrunc, filter); | 242 line << L"Hidden "; |
| 243 line << std::setw( 12 ) << std::left << tag << L" - "; | |
| 244 line << src_truncated << L" "; | |
| 245 line << filter; | |
| 213 | 246 |
| 214 DebugResult(blocking); | 247 DebugResult( line.str() ); |
| 215 } | 248 } |
| 216 | 249 |
| 217 | 250 |
| 218 void CPluginDebug::DebugResultClear() | 251 void CPluginDebug::DebugResultClear() |
| 219 { | 252 { |
| 220 CPluginDebugLock lock; | 253 CPluginDebugLock lock; |
| 221 if (lock.IsLocked()) | 254 if (lock.IsLocked()) |
| 222 { | 255 { |
| 223 ::DeleteFile(CPluginSettings::GetDataPath("debug_result.txt")); | 256 ::DeleteFile(CPluginSettings::GetDataPath(L"debug_result.txt").c_str()); |
| 224 } | 257 } |
| 225 } | 258 } |
| 226 | 259 |
| 227 #endif // ENABLE_DEBUG_RESULT | 260 #endif // ENABLE_DEBUG_RESULT |
| 228 | 261 |
| 229 | 262 |
| 230 #ifdef ENABLE_DEBUG_RESULT_IGNORED | 263 #ifdef ENABLE_DEBUG_RESULT_IGNORED |
| 231 | 264 |
| 232 void CPluginDebug::DebugResultIgnoring(const CString& type, const CString& src, const CString& domain) | 265 void CPluginDebug::DebugResultIgnoring(const std::wstring & type, const std::wst ring & src, const std::wstring & domain) |
| 233 { | 266 { |
| 234 CString srcTrunc = src; | 267 std::wstring src_truncated( src ); |
| 235 if (srcTrunc.GetLength() > 100) | 268 ABP::debug::truncate_source( src_truncated ); |
| 236 { | |
| 237 srcTrunc = src.Left(67) + L"..." + src.Right(30); | |
| 238 } | |
| 239 | 269 |
| 240 CString blocking; | 270 std::wostringstream line; |
| 241 blocking.Format(L"Ignored %-12s %s %s", type, domain.IsEmpty()? L"-" : doma in, srcTrunc); | 271 line << L"Ignored "; |
| 272 line << std::setw( 12 ) << std::left << type << L" "; | |
| 273 line << ( domain.empty() ? L"-" : domain ); | |
| 274 line << src_truncated; | |
| 242 | 275 |
| 243 DebugResult(blocking); | 276 DebugResult( line.str() ); |
| 244 } | 277 } |
| 245 | 278 |
| 246 #endif // ENABLE_DEBUG_RESULT_IGNORED | 279 #endif // ENABLE_DEBUG_RESULT_IGNORED |
| OLD | NEW |