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 
51 namespace ns3 {
52 
53 NS_LOG_COMPONENT_DEFINE ("FatalImpl");
54 
55 namespace FatalImpl {
56 
62 namespace {
63 
71 std::list<std::ostream*> **PeekStreamList (void)
72 {
74  static std::list<std::ostream*> *streams = 0;
75  return &streams;
76 }
77 
84 std::list<std::ostream*> *GetStreamList (void)
85 {
87  std::list<std::ostream*> **pstreams = PeekStreamList ();
88  if (*pstreams == 0)
89  {
90  *pstreams = new std::list<std::ostream*> ();
91  }
92  return *pstreams;
93 }
94 
111 {
113  {
114  NS_LOG_FUNCTION (this);
115  std::list<std::ostream*> **pstreams = PeekStreamList ();
116  delete *pstreams;
117  *pstreams = 0;
118  }
119 };
120 } // anonymous namespace
121 
122 void
123 RegisterStream (std::ostream* stream)
124 {
125  NS_LOG_FUNCTION (stream);
126  GetStreamList ()->push_back (stream);
127 }
128 
129 void
130 UnregisterStream (std::ostream* stream)
131 {
132  NS_LOG_FUNCTION (stream);
133  std::list<std::ostream*> **pl = PeekStreamList ();
134  if (*pl == 0)
135  {
136  return;
137  }
138  (*pl)->remove (stream);
139  if ((*pl)->empty ())
140  {
141  delete *pl;
142  *pl = 0;
143  }
144 }
145 
152 namespace {
153 
163 void sigHandler (int sig)
164 {
165  NS_LOG_FUNCTION (sig);
166  FlushStreams ();
167  std::abort ();
168 }
169 } // anonymous namespace
170 
171 void
173 {
175  std::list<std::ostream*> **pl = PeekStreamList ();
176  if (*pl == 0)
177  {
178  return;
179  }
180 
181 
182  /* Override default SIGSEGV handler - will flush subsequent
183  * streams even if one of the stream pointers is bad.
184  * The SIGSEGV override should only be active for the
185  * duration of this function. */
186  struct sigaction hdl;
187  hdl.sa_handler=sigHandler;
188  sigaction (SIGSEGV, &hdl, 0);
189 
190  std::list<std::ostream*> *l = *pl;
191 
192  /* Need to do it this way in case any of the ostream* causes SIGSEGV */
193  while (!l->empty ())
194  {
195  std::ostream* s (l->front ());
196  l->pop_front ();
197  s->flush ();
198  }
199 
200  /* Restore default SIGSEGV handler (Not that it matters anyway) */
201  hdl.sa_handler=SIG_DFL;
202  sigaction (SIGSEGV, &hdl, 0);
203 
204  /* Flush all opened FILE* */
205  std::fflush (0);
206 
207  /* Flush stdandard streams - shouldn't be required (except for clog) */
208  std::cout.flush ();
209  std::cerr.flush ();
210  std::clog.flush ();
211 
212  delete l;
213  *pl = 0;
214 }
215 
216 } // namespace FatalImpl
217 
218 } // namespace ns3
Declaration of RegisterStream(), UnregisterStream(), and FlushStreams().
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void sigHandler(int sig)
Overrides normal SIGSEGV handler once the HandleTerminate function is run.
Definition: fatal-impl.cc:163
void FlushStreams(void)
Flush all currently registered streams.
Definition: fatal-impl.cc:172
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Destructor for the list of fatal streams.
Definition: fatal-impl.cc:110
std::list< std::ostream * > * GetStreamList(void)
Get the stream list, initializing it if necessary.
Definition: fatal-impl.cc:84
void RegisterStream(std::ostream *stream)
Register a stream to be flushed on abnormal exit.
Definition: fatal-impl.cc:123
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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:71
void UnregisterStream(std::ostream *stream)
Unregister a stream for flushing on abnormal exit.
Definition: fatal-impl.cc:130
Debug message logging.