BUG: UListIO: byteSize overflowing on really big faceLists
[OpenFOAM-2.0.x.git] / src / OSspecific / POSIX / signals / sigFpe.C
bloba275fd7a3ad34cb7951bdc76d110451420dea5c4
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
11     OpenFOAM is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by
13     the Free Software Foundation, either version 3 of the License, or
14     (at your option) any later version.
16     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "sigFpe.H"
27 #include "error.H"
28 #include "JobInfo.H"
29 #include "OSspecific.H"
30 #include "IOstreams.H"
32 #ifdef LINUX_GNUC
34 #   ifndef __USE_GNU
35 #       define __USE_GNU
36 #   endif
38 #   include <fenv.h>
39 #   include <malloc.h>
41 #elif defined(sgiN32) || defined(sgiN32Gcc)
43 #   include <sigfpe.h>
45 #endif
47 #include <stdint.h>
49 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
51 struct sigaction Foam::sigFpe::oldAction_;
54 #ifdef LINUX
56 void *(*Foam::sigFpe::oldMallocHook_)(size_t, const void *) = NULL;
58 void* Foam::sigFpe::nanMallocHook_(size_t size, const void *caller)
60     void *result;
62     // Restore all old hooks
63     __malloc_hook = oldMallocHook_;
65     // Call recursively
66     result = malloc(size);
68     // initialize to signalling NaN
69 #   ifdef WM_SP
71     const uint32_t sNAN = 0x7ff7fffflu;
72     uint32_t* dPtr = reinterpret_cast<uint32_t*>(result);
74 #   else
76     const uint64_t sNAN = 0x7ff7ffffffffffffllu;
77     uint64_t* dPtr = reinterpret_cast<uint64_t*>(result);
79 #   endif
81     const size_t nScalars = size/sizeof(scalar);
82     for (size_t i = 0; i < nScalars; ++i)
83     {
84         *dPtr++ = sNAN;
85     }
88     // Restore our own hooks
89     __malloc_hook = nanMallocHook_;
91     return result;
94 #endif
97 #ifdef LINUX_GNUC
99 void Foam::sigFpe::sigHandler(int)
101     // Reset old handling
102     if (sigaction(SIGFPE, &oldAction_, NULL) < 0)
103     {
104         FatalErrorIn
105         (
106             "Foam::sigSegv::sigHandler()"
107         )   << "Cannot reset SIGFPE trapping"
108             << abort(FatalError);
109     }
111     // Update jobInfo file
112     jobInfo.signalEnd();
114     error::printStack(Perr);
116     // Throw signal (to old handler)
117     raise(SIGFPE);
120 #endif
123 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
125 Foam::sigFpe::sigFpe()
127     oldAction_.sa_handler = NULL;
131 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
133 Foam::sigFpe::~sigFpe()
135     if (env("FOAM_SIGFPE"))
136     {
137 #       ifdef LINUX_GNUC
139         // Reset signal
140         if (oldAction_.sa_handler && sigaction(SIGFPE, &oldAction_, NULL) < 0)
141         {
142             FatalErrorIn
143             (
144                 "Foam::sigFpe::~sigFpe()"
145             )   << "Cannot reset SIGFPE trapping"
146                 << abort(FatalError);
147         }
149 #       endif
150     }
152     if (env("FOAM_SETNAN"))
153     {
154 #       ifdef LINUX_GNUC
156         // Reset to standard malloc
157         if (oldAction_.sa_handler)
158         {
159             __malloc_hook = oldMallocHook_;
160         }
162 #       endif
163     }
167 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
169 void Foam::sigFpe::set(const bool verbose)
171     if (oldAction_.sa_handler)
172     {
173         FatalErrorIn
174         (
175             "Foam::sigFpe::set()"
176         )   << "Cannot call sigFpe::set() more than once"
177             << abort(FatalError);
178     }
180     if (env("FOAM_SIGFPE"))
181     {
182         bool supported = false;
184 #       ifdef LINUX_GNUC
185         supported = true;
187         feenableexcept
188         (
189             FE_DIVBYZERO
190           | FE_INVALID
191           | FE_OVERFLOW
192         );
194         struct sigaction newAction;
195         newAction.sa_handler = sigHandler;
196         newAction.sa_flags = SA_NODEFER;
197         sigemptyset(&newAction.sa_mask);
198         if (sigaction(SIGFPE, &newAction, &oldAction_) < 0)
199         {
200             FatalErrorIn
201             (
202                 "Foam::sigFpe::set()"
203             )   << "Cannot set SIGFPE trapping"
204                 << abort(FatalError);
205         }
208 #       elif defined(sgiN32) || defined(sgiN32Gcc)
209         supported = true;
211         sigfpe_[_DIVZERO].abort=1;
212         sigfpe_[_OVERFL].abort=1;
213         sigfpe_[_INVALID].abort=1;
215         sigfpe_[_DIVZERO].trace=1;
216         sigfpe_[_OVERFL].trace=1;
217         sigfpe_[_INVALID].trace=1;
219         handle_sigfpes
220         (
221             _ON,
222             _EN_DIVZERO
223           | _EN_INVALID
224           | _EN_OVERFL,
225             0,
226             _ABORT_ON_ERROR,
227             NULL
228         );
230 #       endif
233         if (verbose)
234         {
235             if (supported)
236             {
237                 Info<< "sigFpe : Enabling floating point exception trapping"
238                     << " (FOAM_SIGFPE)." << endl;
239             }
240             else
241             {
242                 Info<< "sigFpe : Floating point exception trapping"
243                     << " - not supported on this platform" << endl;
244             }
245         }
246     }
249     if (env("FOAM_SETNAN"))
250     {
251         bool supported = false;
253 #       ifdef LINUX_GNUC
254         supported = true;
256         // Set our malloc
257         __malloc_hook = Foam::sigFpe::nanMallocHook_;
259 #       endif
262         if (verbose)
263         {
264             if (supported)
265             {
266             Info<< "SetNaN : Initialising allocated memory to NaN"
267                 << " (FOAM_SETNAN)." << endl;
268             }
269             else
270             {
271                 Info<< "SetNaN : Initialise allocated memory to NaN"
272                     << " - not supported on this platform" << endl;
273             }
274         }
275     }
279 // ************************************************************************* //