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