1 //
2 // Debugger.cpp
3 //
4 // Library: Foundation
5 // Package: Core
6 // Module:  Debugger
7 //
8 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9 // and Contributors.
10 //
11 // SPDX-License-Identifier:	BSL-1.0
12 //
13 
14 
15 #include "Poco/Debugger.h"
16 #include <sstream>
17 #include <cstdlib>
18 #include <cstdio>
19 #if defined(POCO_OS_FAMILY_WINDOWS)
20 	#include "Poco/UnWindows.h"
21 #elif defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS)
22 	#include <unistd.h>
23 	#include <signal.h>
24 #endif
25 #include "Poco/UnicodeConverter.h"
26 
27 
28 // NOTE: In this module, we use the C library functions (fputs) for,
29 // output since, at the time we're called, the C++ iostream objects std::cout, etc.
30 // might not have been initialized yet.
31 
32 
33 namespace Poco {
34 
35 
isAvailable()36 bool Debugger::isAvailable()
37 {
38 #if defined(_DEBUG)
39 	#if defined(POCO_OS_FAMILY_WINDOWS)
40 		#if defined(_WIN32_WCE)
41 			#if (_WIN32_WCE >= 0x600)
42 				BOOL isDebuggerPresent;
43 				if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebuggerPresent))
44 				{
45 					return isDebuggerPresent ? true : false;
46 				}
47 				return false;
48 			#else
49 				return false;
50 			#endif
51 		#else
52 			return IsDebuggerPresent() ? true : false;
53 		#endif
54 	#elif defined(POCO_VXWORKS)
55 		return false;
56 	#elif defined(POCO_OS_FAMILY_UNIX)
57 		return std::getenv("POCO_ENABLE_DEBUGGER") ? true : false;
58 	#endif
59 #else
60 	return false;
61 #endif
62 }
63 
64 
message(const std::string & msg)65 void Debugger::message(const std::string& msg)
66 {
67 #if defined(_DEBUG)
68 	std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
69 	std::fputs(msg.c_str(), stderr);
70 	std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
71 	#if defined(POCO_OS_FAMILY_WINDOWS)
72 	if (isAvailable())
73 	{
74 		std::wstring umsg;
75 		UnicodeConverter::toUTF16(msg, umsg);
76 		umsg += '\n';
77 		OutputDebugStringW(umsg.c_str());
78 	}
79 	#endif
80 #endif
81 }
82 
83 
message(const std::string & msg,const char * file,int line)84 void Debugger::message(const std::string& msg, const char* file, int line)
85 {
86 #if defined(_DEBUG)
87 	std::ostringstream str;
88 	str << msg << " [in file \"" << file << "\", line " << line << "]";
89 	message(str.str());
90 #endif
91 }
92 
93 
enter()94 void Debugger::enter()
95 {
96 #if defined(_DEBUG)
97 	#if defined(POCO_OS_FAMILY_WINDOWS)
98 	if (isAvailable())
99 	{
100 		DebugBreak();
101 	}
102 	#elif defined(POCO_VXWORKS)
103 	{
104 		// not supported
105 	}
106 	#elif defined(POCO_OS_FAMILY_UNIX)
107 	if (isAvailable())
108 	{
109 		kill(getpid(), SIGINT);
110 	}
111 	#endif
112 #endif
113 }
114 
115 
enter(const std::string & msg)116 void Debugger::enter(const std::string& msg)
117 {
118 #if defined(_DEBUG)
119 	message(msg);
120 	enter();
121 #endif
122 }
123 
124 
enter(const std::string & msg,const char * file,int line)125 void Debugger::enter(const std::string& msg, const char* file, int line)
126 {
127 #if defined(_DEBUG)
128 	message(msg, file, line);
129 	enter();
130 #endif
131 }
132 
133 
enter(const char * file,int line)134 void Debugger::enter(const char* file, int line)
135 {
136 #if defined(_DEBUG)
137 	message("BREAK", file, line);
138 	enter();
139 #endif
140 }
141 
142 
143 } // namespace Poco
144