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#elif defined(POCO_OS_FAMILY_VMS)
25 #include <lib$routines.h>
26 #include <ssdef.h>
27#endif
28#if !defined(POCO_NO_WSTRING)
29#include "Poco/UnicodeConverter.h"
30#endif
31
32
33// NOTE: In this module, we use the C library functions (fputs) for,
34// output since, at the time we're called, the C++ iostream objects std::cout, etc.
35// might not have been initialized yet.
36
37
38namespace Poco {
39
40
41bool Debugger::isAvailable()
42{
43#if defined(_DEBUG)
44 #if defined(POCO_OS_FAMILY_WINDOWS)
45 #if defined(_WIN32_WCE)
46 #if (_WIN32_WCE >= 0x600)
47 BOOL isDebuggerPresent;
48 if (CheckRemoteDebuggerPresent(GetCurrentProcess(), &isDebuggerPresent))
49 {
50 return isDebuggerPresent ? true : false;
51 }
52 return false;
53 #else
54 return false;
55 #endif
56 #else
57 return IsDebuggerPresent() ? true : false;
58 #endif
59 #elif defined(POCO_VXWORKS)
60 return false;
61 #elif defined(POCO_OS_FAMILY_UNIX)
62 return std::getenv("POCO_ENABLE_DEBUGGER") ? true : false;
63 #elif defined(POCO_OS_FAMILY_VMS)
64 return true;
65 #endif
66#else
67 return false;
68#endif
69}
70
71
72void Debugger::message(const std::string& msg)
73{
74#if defined(_DEBUG)
75 std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
76 std::fputs(msg.c_str(), stderr);
77 std::fputs("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", stderr);
78#if defined(POCO_OS_FAMILY_WINDOWS)
79 if (isAvailable())
80 {
81#if !defined(POCO_NO_WSTRING)
82 std::wstring umsg;
83 UnicodeConverter::toUTF16(msg, umsg);
84 umsg += '\n';
85 OutputDebugStringW(umsg.c_str());
86#endif // POCO_NO_WSTRING
87 }
88#elif defined(POCO_OS_FAMILY_UNIX)
89#elif defined(POCO_OS_FAMILY_VMS)
90#endif // POCO_OS_FAMILY_*
91#endif // _DEBUG
92}
93
94
95void Debugger::message(const std::string& msg, const char* file, int line)
96{
97#if defined(_DEBUG)
98 std::ostringstream str;
99 str << msg << " [in file \"" << file << "\", line " << line << "]";
100 message(str.str());
101#endif
102}
103
104
105void Debugger::enter()
106{
107#if defined(_DEBUG)
108 #if defined(POCO_OS_FAMILY_WINDOWS)
109 if (isAvailable())
110 {
111 DebugBreak();
112 }
113 #elif defined(POCO_VXWORKS)
114 {
115 // not supported
116 }
117 #elif defined(POCO_OS_FAMILY_UNIX)
118 if (isAvailable())
119 {
120 kill(getpid(), SIGINT);
121 }
122 #elif defined(POCO_OS_FAMILY_VMS)
123 {
124 const char* cmd = "\012SHOW CALLS";
125 lib$signal(SS$_DEBUG, 1, cmd);
126 }
127 #endif
128#endif
129}
130
131
132void Debugger::enter(const std::string& msg)
133{
134#if defined(_DEBUG)
135 message(msg);
136 enter();
137#endif
138}
139
140
141void Debugger::enter(const std::string& msg, const char* file, int line)
142{
143#if defined(_DEBUG)
144 message(msg, file, line);
145 enter();
146#endif
147}
148
149
150void Debugger::enter(const char* file, int line)
151{
152#if defined(_DEBUG)
153 message("BREAK", file, line);
154 enter();
155#endif
156}
157
158
159} // namespace Poco
160