A Discrete-Event Network Simulator
API
fatal-impl.cc
Go to the documentation of this file.
1/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
3 * Copyright (c) 2010 NICTA
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Author: Quincy Tse <quincy.tse@nicta.com.au>
19 */
20#include "fatal-impl.h"
21#include "log.h"
22
23#include <iostream>
24#include <list>
25
26#include <cstdlib>
27#include <cstdio>
28
29#include <csignal>
30
53namespace ns3 {
54
55NS_LOG_COMPONENT_DEFINE ("FatalImpl");
56
57namespace FatalImpl {
58
64namespace {
65
73std::list<std::ostream*> ** PeekStreamList (void)
74{
76 static std::list<std::ostream*> *streams = 0;
77 return &streams;
78}
79
86std::list<std::ostream*> * GetStreamList (void)
87{
89 std::list<std::ostream*> **pstreams = PeekStreamList ();
90 if (*pstreams == 0)
91 {
92 *pstreams = new std::list<std::ostream*> ();
93 }
94 return *pstreams;
95}
96
97} // unnamed namespace
98
99void
100RegisterStream (std::ostream* stream)
101{
102 NS_LOG_FUNCTION (stream);
103 GetStreamList ()->push_back (stream);
104}
105
106void
107UnregisterStream (std::ostream* stream)
108{
109 NS_LOG_FUNCTION (stream);
110 std::list<std::ostream*> **pl = PeekStreamList ();
111 if (*pl == 0)
112 {
113 return;
114 }
115 (*pl)->remove (stream);
116 if ((*pl)->empty ())
117 {
118 delete *pl;
119 *pl = 0;
120 }
121}
122
129namespace {
130
140void sigHandler (int sig)
141{
142 NS_LOG_FUNCTION (sig);
143 FlushStreams ();
144 std::abort ();
145}
146} // unnamed namespace
147
148void
150{
152 std::list<std::ostream*> **pl = PeekStreamList ();
153 if (*pl == 0)
154 {
155 return;
156 }
157
158
159 /* Override default SIGSEGV handler - will flush subsequent
160 * streams even if one of the stream pointers is bad.
161 * The SIGSEGV override should only be active for the
162 * duration of this function. */
163 struct sigaction hdl;
164 hdl.sa_handler = sigHandler;
165 sigaction (SIGSEGV, &hdl, 0);
166
167 std::list<std::ostream*> *l = *pl;
168
169 /* Need to do it this way in case any of the ostream* causes SIGSEGV */
170 while (!l->empty ())
171 {
172 std::ostream* s (l->front ());
173 l->pop_front ();
174 s->flush ();
175 }
176
177 /* Restore default SIGSEGV handler (Not that it matters anyway) */
178 hdl.sa_handler = SIG_DFL;
179 sigaction (SIGSEGV, &hdl, 0);
180
181 /* Flush all opened FILE* */
182 std::fflush (0);
183
184 /* Flush stdandard streams - shouldn't be required (except for clog) */
185 std::cout.flush ();
186 std::cerr.flush ();
187 std::clog.flush ();
188
189 delete l;
190 *pl = 0;
191}
192
193} // namespace FatalImpl
194
195} // namespace ns3
ns3::FatalImpl::RegisterStream(), ns3::FatalImpl::UnregisterStream(), and ns3::FatalImpl::FlushStream...
std::list< std::ostream * > * GetStreamList(void)
Get the stream list, initializing it if necessary.
Definition: fatal-impl.cc:86
void UnregisterStream(std::ostream *stream)
Unregister a stream for flushing on abnormal exit.
Definition: fatal-impl.cc:107
void sigHandler(int sig)
Overrides normal SIGSEGV handler once the HandleTerminate function is run.
Definition: fatal-impl.cc:140
std::list< std::ostream * > ** PeekStreamList(void)
Static variable pointing to the list of output streams to be flushed on fatal errors.
Definition: fatal-impl.cc:73
void RegisterStream(std::ostream *stream)
Register a stream to be flushed on abnormal exit.
Definition: fatal-impl.cc:100
void FlushStreams(void)
Flush all currently registered streams.
Definition: fatal-impl.cc:149
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
Debug message logging.
Every class exported by the ns3 library is enclosed in the ns3 namespace.