A Discrete-Event Network Simulator
Home
Tutorials ▼
English
Documentation ▼
Installation
Manual
Models
Contributing
Wiki
Development ▼
API Docs
Issue Tracker
Merge Requests
API
Loading...
Searching...
No Matches
fatal-impl.cc
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2010 NICTA
3
*
4
* SPDX-License-Identifier: GPL-2.0-only
5
*
6
* Author: Quincy Tse <quincy.tse@nicta.com.au>
7
*/
8
#include "
fatal-impl.h
"
9
10
#include "
log.h
"
11
12
#include <csignal>
13
#include <cstdio>
14
#include <cstdlib>
15
#include <iostream>
16
#include <list>
17
18
#ifdef __WIN32__
19
struct
sigaction
20
{
21
void (*sa_handler)(int);
22
int
sa_flags;
23
int
sa_mask;
24
};
25
26
int
27
sigaction(
int
sig,
struct
sigaction* action,
struct
sigaction* old)
28
{
29
if
(sig == -1)
30
{
31
return
0;
32
}
33
if
(old ==
nullptr
)
34
{
35
if
(signal(sig, SIG_DFL) == SIG_ERR)
36
{
37
return
-1;
38
}
39
}
40
else
41
{
42
if
(signal(sig,
action
->sa_handler) == SIG_ERR)
43
{
44
return
-1;
45
}
46
}
47
return
0;
48
}
49
#endif
50
51
/**
52
* \file
53
* \ingroup fatalimpl
54
* \brief ns3::FatalImpl::RegisterStream(), ns3::FatalImpl::UnregisterStream(),
55
* and ns3::FatalImpl::FlushStreams() implementations;
56
* see Implementation note!
57
*
58
* \note Implementation.
59
*
60
* The singleton pattern we use here is tricky because we have to ensure:
61
*
62
* - RegisterStream() succeeds, even if called before \c main() enters and
63
* before any constructor run in this file.
64
*
65
* - UnregisterStream() succeeds, whether or not FlushStreams() has
66
* been called.
67
*
68
* - All memory allocated with \c new is deleted properly before program exit.
69
*
70
* This is why we go through all the painful hoops below.
71
*/
72
73
namespace
ns3
74
{
75
76
NS_LOG_COMPONENT_DEFINE
(
"FatalImpl"
);
77
78
namespace
FatalImpl
79
{
80
81
/**
82
* \ingroup fatalimpl
83
* Unnamed namespace for fatal streams memory implementation
84
* and signal handler.
85
*/
86
namespace
87
{
88
89
/**
90
* \ingroup fatalimpl
91
* \brief Static variable pointing to the list of output streams
92
* to be flushed on fatal errors.
93
*
94
* \returns The address of the static pointer.
95
*/
96
std::list<std::ostream*>**
97
PeekStreamList
()
98
{
99
NS_LOG_FUNCTION_NOARGS
();
100
static
std::list<std::ostream*>* streams =
nullptr
;
101
return
&streams;
102
}
103
104
/**
105
* \ingroup fatalimpl
106
* \brief Get the stream list, initializing it if necessary.
107
*
108
* \returns The stream list.
109
*/
110
std::list<std::ostream*>*
111
GetStreamList
()
112
{
113
NS_LOG_FUNCTION_NOARGS
();
114
std::list<std::ostream*>** pstreams =
PeekStreamList
();
115
if
(*pstreams ==
nullptr
)
116
{
117
*pstreams =
new
std::list<std::ostream*>();
118
}
119
return
*pstreams;
120
}
121
122
}
// unnamed namespace
123
124
void
125
RegisterStream
(std::ostream* stream)
126
{
127
NS_LOG_FUNCTION
(stream);
128
GetStreamList()->push_back(stream);
129
}
130
131
void
132
UnregisterStream
(std::ostream* stream)
133
{
134
NS_LOG_FUNCTION
(stream);
135
std::list<std::ostream*>** pl = PeekStreamList();
136
if
(*pl ==
nullptr
)
137
{
138
return
;
139
}
140
(*pl)->remove(stream);
141
if
((*pl)->empty())
142
{
143
delete
*pl;
144
*pl =
nullptr
;
145
}
146
}
147
148
/**
149
* \ingroup fatalimpl
150
* Unnamed namespace for fatal streams signal handler.
151
*
152
* This is private to the fatal implementation.
153
*/
154
namespace
155
{
156
157
/**
158
* \ingroup fatalimpl
159
* \brief Overrides normal SIGSEGV handler once the HandleTerminate
160
* function is run.
161
*
162
* This is private to the fatal implementation.
163
*
164
* \param [in] sig The signal condition.
165
*/
166
void
167
sigHandler
(
int
sig)
168
{
169
NS_LOG_FUNCTION
(sig);
170
FlushStreams
();
171
std::abort();
172
}
173
}
// unnamed namespace
174
175
void
176
FlushStreams
()
177
{
178
NS_LOG_FUNCTION_NOARGS
();
179
std::list<std::ostream*>** pl = PeekStreamList();
180
if
(*pl ==
nullptr
)
181
{
182
return
;
183
}
184
185
/* Override default SIGSEGV handler - will flush subsequent
186
* streams even if one of the stream pointers is bad.
187
* The SIGSEGV override should only be active for the
188
* duration of this function. */
189
struct
sigaction hdl;
190
hdl.sa_handler = sigHandler;
191
sigaction(SIGSEGV, &hdl,
nullptr
);
192
193
std::list<std::ostream*>* l = *pl;
194
195
/* Need to do it this way in case any of the ostream* causes SIGSEGV */
196
while
(!l->empty())
197
{
198
std::ostream* s(l->front());
199
l->pop_front();
200
s->flush();
201
}
202
203
/* Restore default SIGSEGV handler (Not that it matters anyway) */
204
hdl.sa_handler = SIG_DFL;
205
sigaction(SIGSEGV, &hdl,
nullptr
);
206
207
/* Flush all opened FILE* */
208
std::fflush(
nullptr
);
209
210
/* Flush stdandard streams - shouldn't be required (except for clog) */
211
std::cout.flush();
212
std::cerr.flush();
213
std::clog.flush();
214
215
delete
l;
216
*pl =
nullptr
;
217
}
218
219
}
// namespace FatalImpl
220
221
}
// namespace ns3
fatal-impl.h
ns3::FatalImpl::RegisterStream(), ns3::FatalImpl::UnregisterStream(), and ns3::FatalImpl::FlushStream...
ns3::FatalImpl::UnregisterStream
void UnregisterStream(std::ostream *stream)
Unregister a stream for flushing on abnormal exit.
Definition
fatal-impl.cc:132
ns3::FatalImpl::anonymous_namespace{fatal-impl.cc}::PeekStreamList
std::list< std::ostream * > ** PeekStreamList()
Static variable pointing to the list of output streams to be flushed on fatal errors.
Definition
fatal-impl.cc:97
ns3::FatalImpl::anonymous_namespace{fatal-impl.cc}::sigHandler
void sigHandler(int sig)
Overrides normal SIGSEGV handler once the HandleTerminate function is run.
Definition
fatal-impl.cc:167
ns3::FatalImpl::anonymous_namespace{fatal-impl.cc}::GetStreamList
std::list< std::ostream * > * GetStreamList()
Get the stream list, initializing it if necessary.
Definition
fatal-impl.cc:111
ns3::FatalImpl::RegisterStream
void RegisterStream(std::ostream *stream)
Register a stream to be flushed on abnormal exit.
Definition
fatal-impl.cc:125
ns3::FatalImpl::FlushStreams
void FlushStreams()
Flush all currently registered streams.
Definition
fatal-impl.cc:176
NS_LOG_COMPONENT_DEFINE
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition
log.h:191
NS_LOG_FUNCTION_NOARGS
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition
log-macros-enabled.h:195
NS_LOG_FUNCTION
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Definition
log-macros-enabled.h:229
log.h
Debug message logging.
check-style-clang-format.action
action
Definition
check-style-clang-format.py:775
ns3
Every class exported by the ns3 library is enclosed in the ns3 namespace.
src
core
model
fatal-impl.cc
Generated on Fri Nov 8 2024 13:58:59 for ns-3 by
1.11.0