A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 
31 NS_LOG_COMPONENT_DEFINE ("FatalImpl");
32 
33 namespace ns3 {
34 namespace FatalImpl {
35 
49 /* File-scope */
50 namespace {
51 std::list<std::ostream*> **PeekStreamList (void)
52 {
54  static std::list<std::ostream*> *streams = 0;
55  return &streams;
56 }
57 std::list<std::ostream*> *GetStreamList (void)
58 {
60  std::list<std::ostream*> **pstreams = PeekStreamList ();
61  if (*pstreams == 0)
62  {
63  *pstreams = new std::list<std::ostream*> ();
64  }
65  return *pstreams;
66 }
67 struct destructor
68 {
70  {
71  NS_LOG_FUNCTION (this);
72  std::list<std::ostream*> **pstreams = PeekStreamList ();
73  delete *pstreams;
74  *pstreams = 0;
75  }
76 };
77 }
78 
79 void
80 RegisterStream (std::ostream* stream)
81 {
82  NS_LOG_FUNCTION (stream);
83  GetStreamList ()->push_back (stream);
84 }
85 
86 void
87 UnregisterStream (std::ostream* stream)
88 {
89  NS_LOG_FUNCTION (stream);
90  std::list<std::ostream*> **pl = PeekStreamList ();
91  if (*pl == 0)
92  {
93  return;
94  }
95  (*pl)->remove (stream);
96  if ((*pl)->empty ())
97  {
98  delete *pl;
99  *pl = 0;
100  }
101 }
102 
103 
104 namespace {
105 /* Overrides normal SIGSEGV handler once the
106  * HandleTerminate function is run. */
107 void sigHandler (int sig)
108 {
109  NS_LOG_FUNCTION (sig);
110  FlushStreams ();
111  std::abort ();
112 }
113 }
114 
115 void
117 {
119  std::list<std::ostream*> **pl = PeekStreamList ();
120  if (*pl == 0)
121  {
122  return;
123  }
124 
125 
126  /* Override default SIGSEGV handler - will flush subsequent
127  * streams even if one of the stream pointers is bad.
128  * The SIGSEGV override should only be active for the
129  * duration of this function. */
130  struct sigaction hdl;
131  hdl.sa_handler=sigHandler;
132  sigaction (SIGSEGV, &hdl, 0);
133 
134  std::list<std::ostream*> *l = *pl;
135 
136  /* Need to do it this way in case any of the ostream* causes SIGSEGV */
137  while (!l->empty ())
138  {
139  std::ostream* s (l->front ());
140  l->pop_front ();
141  s->flush ();
142  }
143 
144  /* Restore default SIGSEGV handler (Not that it matters anyway) */
145  hdl.sa_handler=SIG_DFL;
146  sigaction (SIGSEGV, &hdl, 0);
147 
148  /* Flush all opened FILE* */
149  std::fflush (0);
150 
151  /* Flush stdandard streams - shouldn't be required (except for clog) */
152  std::cout.flush ();
153  std::cerr.flush ();
154  std::clog.flush ();
155 
156  delete l;
157  *pl = 0;
158 }
159 
160 } //FatalImpl
161 } //ns3
NS_LOG_COMPONENT_DEFINE("FatalImpl")
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
std::list< std::ostream * > ** PeekStreamList(void)
Definition: fatal-impl.cc:51
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
void RegisterStream(std::ostream *stream)
Register a stream to be flushed on abnormal exit.
Definition: fatal-impl.cc:80
Ptr< SampleEmitter > s
void FlushStreams(void)
Flush all currently registered streams.
Definition: fatal-impl.cc:116
std::list< std::ostream * > * GetStreamList(void)
Definition: fatal-impl.cc:57
void UnregisterStream(std::ostream *stream)
Unregister a stream for flushing on abnormal exit.
Definition: fatal-impl.cc:87