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