14#include "arcane/utils/ArcanePrecomp.h"
16#include "arcane/utils/Iostream.h"
17#include "arcane/utils/ValueConvert.h"
18#include "arcane/utils/StdHeader.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arcane/utils/FatalErrorException.h"
21#include "arcane/utils/SignalException.h"
22#include "arcane/utils/TimeoutException.h"
23#include "arcane/utils/ArithmeticException.h"
24#include "arcane/utils/IStackTraceService.h"
25#include "arcane/utils/TraceInfo.h"
26#include "arcane/utils/OStringStream.h"
27#include "arcane/utils/IThreadImplementation.h"
29#include "arcane/utils/NullThreadMng.h"
30#include "arcane/utils/CriticalSection.h"
34#ifndef ARCANE_OS_WIN32
40#ifndef ARCANE_OS_WIN32
44#define USE_SIGACTION 1
57 typedef void (*fSignalFunc)(int);
63template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
double& v,
const String& s)
65 const char* ptr = s.localstr();
67 if(s==
"infinity" || s==
"inf")
69 v = std::numeric_limits<double>::infinity();
74 v = ::strtod(ptr,&ptr2);
75 return (ptr2!=(ptr+s.length()));
77template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
float& v,
const String& s)
80 bool r = builtInGetValue(z,s);
84template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
long& v,
const String& s)
86 const char* ptr = s.localstr();
88 v = ::strtol(ptr,&ptr2,0);
89 return (ptr2!=(ptr+s.length()));
91template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
int& v,
const String& s)
94 bool r = builtInGetValue(z,s);
98template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
short& v,
const String& s)
101 bool r = builtInGetValue(z,s);
105template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
unsigned long& v,
const String& s)
107 const char* ptr = s.localstr();
109 v = ::strtoul(ptr,&ptr2,0);
110 return (ptr2!=(ptr+s.length()));
112template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
unsigned int& v,
const String& s)
115 bool r = builtInGetValue(z,s);
119template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
unsigned short& v,
const String& s)
122 bool r = builtInGetValue(z,s);
123 v = (
unsigned short)z;
126template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
long long& v,
const String& s)
128 const char* ptr = s.localstr();
130 v = ::strtoll(ptr,&ptr2,0);
131 return (ptr2!=(ptr+s.length()));
133template<> ARCANE_UTILS_EXPORT
bool builtInGetValue(
unsigned long long& v,
const String& s)
135 const char* ptr = s.localstr();
137 v = ::strtoull(ptr,&ptr2,0);
138 return (ptr2!=(ptr+s.length()));
145static bool global_arcane_is_check =
true;
147static bool global_arcane_is_check =
false;
150extern "C++" ARCANE_UTILS_EXPORT
153 return global_arcane_is_check;
156extern "C++" ARCANE_UTILS_EXPORT
159 global_arcane_is_check = v;
162extern "C++" ARCANE_UTILS_EXPORT
178 bool global_arcane_has_thread =
true;
181extern "C++" ARCANE_UTILS_EXPORT
184 return global_arcane_has_thread;
187extern "C++" ARCANE_UTILS_EXPORT
191 global_arcane_has_thread = v;
199extern "C++" ARCANE_UTILS_EXPORT
205 return ti->currentThread();
213extern "C++" ARCANE_UTILS_EXPORT
void
214arcaneSetPauseOnError(
bool v)
219extern "C++" ARCANE_UTILS_EXPORT
void
228extern "C++" ARCANE_UTILS_EXPORT
void
232 cerr <<
"** FATAL: Trying to use a null pointer.\n";
234 throw FatalErrorException(A_FUNCINFO);
242void _doNoReferenceError(
const void* ptr)
244 cerr <<
"** FATAL: Null reference.\n";
245 cerr <<
"** FATAL: Trying to use an item not referenced.\n";
246 cerr <<
"** FATAL: Item is located at memory address " << ptr <<
".\n";
254extern "C++" ARCANE_UTILS_EXPORT
void
257 _doNoReferenceError(ptr);
264extern "C++" ARCANE_UTILS_EXPORT
void
267 _doNoReferenceError(ptr);
274extern "C++" ARCANE_UTILS_EXPORT
void
281 vsnprintf(buffer,256,format,ap);
283 cerr << buffer <<
"\n";
284 cout <<
"*E* " << buffer <<
"\n";
290extern "C++" ARCANE_UTILS_EXPORT
void
291arcaneObsolete(
const char* file,
const char* func,
unsigned long line,
const char* text)
293 cerr << file <<
':' << func <<
':' << line <<
'\n';
294 cerr <<
"usage of this function is deprecated";
296 cerr <<
": " << text;
305typedef void (*
fDoAssert)(
const char*,
const char*,
const char*,size_t);
317ARCANE_UTILS_EXPORT
void
318_doAssert(
const char* text,
const char* file,
const char* func,
size_t line)
320 if (g_do_assert_func)
321 (*g_do_assert_func)(text,file,func,line);
323 std::ostringstream ostr;
324 ostr << text <<
':' << file <<
':' << func <<
':' << line <<
": ";
334extern "C++" ARCANE_UTILS_EXPORT
bool
337 if (g_check_debug_func)
338 return (*g_check_debug_func)(val);
347static fSignalFunc g_signal_func = 0;
351setSignalFunc(fSignalFunc func)
353 fSignalFunc old = g_signal_func;
354 g_signal_func = func;
361#ifdef ARCANE_OS_LINUX
362#define STD_SIGNAL_TYPE 1
365#if STD_SIGNAL_TYPE == 1
366#include <sys/signal.h>
376 (*g_signal_func)(val);
380_MiscSigactionFunc(
int val, siginfo_t*,
void*)
383 (*g_signal_func)(val);
393fSignalFunc default_signal_func_sigsegv = 0;
394fSignalFunc default_signal_func_sigfpe = 0;
395fSignalFunc default_signal_func_sigbus = 0;
396fSignalFunc default_signal_func_sigalrm = 0;
397fSignalFunc default_signal_func_sigvtalrm = 0;
399bool global_already_in_signal =
false;
402extern "C++" ARCANE_UTILS_EXPORT
void
403arcaneRedirectSignals(fSignalFunc sig_func)
405 setSignalFunc(sig_func);
406#if STD_SIGNAL_TYPE == 1
410 sa.sa_flags = SA_SIGINFO | SA_NODEFER;
411 sigemptyset(&sa.sa_mask);
412 sa.sa_sigaction = _MiscSigactionFunc;
414 sigaction(SIGSEGV, &sa,
nullptr);
415 sigaction(SIGFPE, &sa,
nullptr);
416 sigaction(SIGBUS, &sa,
nullptr);
417 sigaction(SIGALRM, &sa,
nullptr);
418 sigaction(SIGVTALRM, &sa,
nullptr);
420 default_signal_func_sigsegv = sigset(SIGSEGV,_MiscSigFunc);
421 default_signal_func_sigfpe = sigset(SIGFPE ,_MiscSigFunc);
422 default_signal_func_sigbus = sigset(SIGBUS ,_MiscSigFunc);
425 default_signal_func_sigalrm = sigset(SIGALRM,_MiscSigFunc);
426 default_signal_func_sigvtalrm = sigset(SIGVTALRM,_MiscSigFunc);
431extern "C++" ARCANE_UTILS_EXPORT
void
432arcaneCallDefaultSignal(
int val)
434#if STD_SIGNAL_TYPE == 1
437 SignalException::eSignalType signal_type = SignalException::ST_Unknown;
441 signal_type = SignalException::ST_SegmentationFault;
444 signal_type = SignalException::ST_FloatingException;
447 signal_type = SignalException::ST_BusError;
451 signal_type = SignalException::ST_Alarm;
460 if (global_already_in_signal)
462 global_already_in_signal =
true;
469 StackTrace stack_trace;
470 IStackTraceService* stack_service = platform::getStackTraceService();
472 stack_trace = stack_service->stackTrace();
473 cerr <<
" Signal exception Stack: " << stack_trace.toString() <<
'\n';
476 cerr <<
" No stack trace service\n";
480 bool do_debug_stack =
false;
481 if (
auto v = Convert::Type<Int32>::tryParseFromEnvironment(
"ARCANE_DUMP_DEBUGGER_STACK_IN_SIGNAL",
true))
482 do_debug_stack = (v.value()!=0);
484 std::cerr <<
"GBDStack pid=" << platform::getProcessId() <<
" stack=" <<
platform::getGDBStack() <<
"\n";
487 std::cerr <<
"SignalCaught: You can dump full stacktrace of the process if environment "
488 "variable ARCANE_DUMP_DEBUGGER_STACK_IN_SIGNAL is set to 1\n";
490 if (signal_type==SignalException::ST_Alarm){
491 global_already_in_signal =
false;
492 throw TimeoutException(
"Arcane.Signal",stack_trace);
494 else if (signal_type==SignalException::ST_FloatingException){
495 global_already_in_signal =
false;
496 cerr <<
"** THROW ARITHMETIC EXCEPTION\n";
498 platform::enableFloatingException(
true);
499 throw ArithmeticException(A_FUNCINFO,stack_trace);
501 throw SignalException(
"Arcane.Signal",stack_trace,signal_type,val);
515 cerr <<
"** pure virtual method called\n";
525 void write(std::ostream& o)
const
527 char* v = (
char*)&m_v;
528 o << m_v <<
" HEXA(";
529 o << (int)v[0] <<
'-';
530 o << (int)v[1] <<
'-';
531 o << (int)v[2] <<
'-';
532 o << (int)v[3] <<
'-';
533 o << (int)v[4] <<
'-';
534 o << (int)v[5] <<
'-';
535 o << (int)v[6] <<
'-';
536 o << (int)v[7] <<
")";
541ARCANE_UTILS_EXPORT std::ostream&
Exception lorsqu'une erreur fatale est survenue.
Interface d'un service implémentant le support des threads.
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
void arcaneNoReferenceErrorCallTerminate(const void *ptr)
Utilisation d'un objet non référencé.
Int64 arcaneCurrentThread()
Retourne l'identifiant du thread courant.
bool arcaneIsCheck()
Vrai si on est en mode vérification.
bool arcaneHasThread()
Vrai si arcane est compilé avec le support des threads ET qu'ils sont actifs.
void arcaneSetHasThread(bool v)
Active ou désactive le support des threads.
void arcaneNullPointerError()
Signalue l'utilisation d'un pointeur nul.
void arcanePrintf(const char *,...)
Encapsulation de la fonction C printf.
void(* fDoAssert)(const char *, const char *, const char *, size_t)
Fonction appelée lorsqu'une assertion échoue.
bool arcaneIsDebug()
Vrai si la macro ARCANE_DEBUG est définie.
void arcaneSetCheck(bool v)
Active ou désactive le mode vérification.
bool(* fCheckDebug)(unsigned int)
Fonction appelée pour indiquer s'il faut afficher l'information de débug.
void arcaneNoReferenceError(const void *ptr)
Utilisation d'un objet non référencé.
bool _checkDebug(unsigned int val)
void _doAssert(const char *text, const char *file, const char *func, size_t line)
void arcaneDebugPause(const char *msg)
Passe en mode pause ou lance une erreur fatale.
std::ostream & operator<<(std::ostream &ostr, eItemKind item_kind)
Opérateur de sortie sur un flot.
ARCCORE_BASE_EXPORT void arccoreDebugPause(const char *msg)
Passe en mode pause ou lance une erreur fatale.
ARCCORE_BASE_EXPORT void arccoreSetPauseOnError(bool v)
Indique si on l'appel à arccoreDebugPause() effectue une pause.