53#if defined(__APPLE__) && defined(__MACH__)
58#ifndef HAVE_FEENABLEEXCEPT
59 auto feenableexcept = [](
int excepts) ->
int {
61 const auto new_excepts = excepts & FE_ALL_EXCEPT;
63 if (fegetenv(&fenv)) {
66#if defined(__x86_64__)
68 const unsigned int old_excepts = fenv.__control & FE_ALL_EXCEPT;
71 fenv.__control &= ~new_excepts;
72 fenv.__mxcsr &= ~(new_excepts << 7);
73#elif defined(__arm64__)
74 if (new_excepts & FE_INVALID) fenv.__fpcr |= __fpcr_trap_invalid;
75 if (new_excepts & FE_DIVBYZERO) fenv.__fpcr |= __fpcr_trap_divbyzero;
76 if (new_excepts & FE_OVERFLOW) fenv.__fpcr |= __fpcr_trap_overflow;
77 if (new_excepts & FE_UNDERFLOW) fenv.__fpcr |= __fpcr_trap_underflow;
78 if (new_excepts & FE_INEXACT) fenv.__fpcr |= __fpcr_trap_inexact;
80#error "MacOS on unknown architecture"
82 return fesetenv(&fenv);
84#define HAVE_FEENABLEEXCEPT 1
87#ifndef HAVE_FEDISABLEEXCEPT
88 auto fedisableexcept = [](
int excepts) ->
int {
90 const auto new_excepts = excepts & FE_ALL_EXCEPT;
93 if (fegetenv(&fenv)) {
96#if defined(__x86_64__)
97 const unsigned int old_excepts = fenv.__control & FE_ALL_EXCEPT;
100 fenv.__control |= new_excepts;
101 fenv.__mxcsr |= new_excepts << 7;
102#elif defined(__arm64__)
103 if (new_excepts & FE_INVALID) fenv.__fpcr &= ~__fpcr_trap_invalid;
104 if (new_excepts & FE_DIVBYZERO) fenv.__fpcr &= ~__fpcr_trap_divbyzero;
105 if (new_excepts & FE_OVERFLOW) fenv.__fpcr &= ~__fpcr_trap_overflow;
106 if (new_excepts & FE_UNDERFLOW) fenv.__fpcr &= ~__fpcr_trap_underflow;
107 if (new_excepts & FE_INEXACT) fenv.__fpcr &= ~__fpcr_trap_inexact;
109#error "MacOS on unknown architecture"
112 return fesetenv(&fenv);
115#define HAVE_FEDISABLEEXCEPT 1
119#ifdef HAVE_FEENABLEEXCEPT
121 int enable_excepts = 0;
123 enable_excepts |= FE_DIVBYZERO;
126 enable_excepts |= FE_INVALID;
129 enable_excepts |= FE_OVERFLOW;
131 feenableexcept(enable_excepts);
134#ifdef HAVE_FEDISABLEEXCEPT
136 int disable_excepts = 0;
138 disable_excepts |= FE_UNDERFLOW;
141 disable_excepts |= FE_INEXACT;
143 fedisableexcept(disable_excepts);
176 for (
int i = 0; i <
NSIG; i++) {
177 if (
mysigs_[i]) signals[i] =
nullptr;
194 for (
int i = 0; i <
NSIG; i++) {
200 static void handler(
int sig) {
201 if (signals[sig]) signals[sig]->
got_signal(sig);
206 if (sig >=
NSIG)
return;
207 typedef void (*handler_type)(int);
208 signal(sig, (handler_type)handler);
214 if (sig >=
NSIG)
return;
215 signal(sig, SIG_DFL);
216 signals[sig] =
nullptr;
268 sprintf(p,
"%3d: ", i);
273 int has_x11_display = (getenv(
"DISPLAY") != 0);
275 if (has_x11_display) {
282void Debugger::resolve_cmd_alias() {
283 if (
cmd_ ==
"gdb_xterm") {
284 cmd_ =
"xterm -title \"$(PREFIX)$(EXEC)\" -e gdb -ex \"set variable debugger_ready_=1\" --pid=$(PID) $(EXEC) &";
285 }
else if (
cmd_ ==
"lldb_xterm") {
286 cmd_ =
"xterm -title \"$(PREFIX)$(EXEC)\" -e lldb -p $(PID) -o \"expr debugger_ready_=1\" &";
300 std::cout <<
prefix_ <<
"Debugger::debug: ";
304 std::cout <<
"no reason given";
310 std::string cmd =
cmd_;
311 std::string::size_type pos;
312 std::string pidvar(
"$(PID)");
313 while ((pos = cmd.find(pidvar)) != std::string::npos) {
315 pidstr += std::to_string(pid);
316 cmd.replace(pos, pidvar.size(), pidstr);
318 std::string execvar(
"$(EXEC)");
319 while ((pos = cmd.find(execvar)) != std::string::npos) {
320 cmd.replace(pos, execvar.size(),
exec_);
322 std::string prefixvar(
"$(PREFIX)");
323 while ((pos = cmd.find(prefixvar)) != std::string::npos) {
324 cmd.replace(pos, prefixvar.size(),
prefix_);
330 std::cout <<
prefix_ <<
"Debugger: starting \"" << cmd <<
"\"" << endl;
332 const auto system_retvalue = system(cmd.c_str());
333 if (system_retvalue != 0) {
334 std::cout <<
prefix_ <<
"Failed debugger launch: system() did not succeed ..." << endl;
338 std::cout <<
prefix_ <<
"Sleeping " <<
sleep_ <<
" seconds to wait for debugger ..." << endl;
342 std::string make_ready_message;
343 if (
cmd_.find(
" gdb ") != std::string::npos ||
cmd_.find(
" lldb ") != std::string::npos) {
345 " configure debugging session (set breakpoints/watchpoints, etc.) then type 'c' to continue running";
348 std::cout <<
prefix_ <<
": waiting for the user ..." << make_ready_message << endl;
354 std::cout <<
prefix_ <<
": waiting for the user to attach a debugger to process " << getpid() <<
" ... " << endl;
365 else if (sig == SIGFPE)
367 else if (sig == SIGHUP)
369 else if (sig == SIGINT)
371 else if (sig == SIGABRT)
374 else if (sig == SIGBUS)
377 else if (sig == SIGTRAP)
380 signame =
"UNKNOWN SIGNAL";
390 std::cout <<
prefix_ <<
"Debugger: exiting" << endl;
393 std::cout <<
prefix_ <<
"Debugger: continuing" << endl;
411#define SIMPLE_STACK (defined(linux) && defined(i386)) || (defined(__OSF1__) && defined(i860))
417 const size_t nframes_to_skip = 2;
418#if defined(HAVE_LIBUNWIND)
419 std::cout << prefix <<
"Debugger::traceback(using libunwind):";
420#elif defined(HAVE_BACKTRACE)
421 std::cout << prefix <<
"Debugger::traceback(using backtrace):";
423#if defined(SIMPLE_STACK)
424 std::cout << prefix <<
"Debugger::traceback:";
426 std::cout << prefix <<
"traceback not available for this arch" << endl;
434 std::cout <<
"no reason given";
438 std::cout << prefix <<
"backtrace returned no state information" << std::endl;
440 std::cout << result.
str(nframes_to_skip) << std::endl;
448 auto debugger = std::make_shared<Debugger>();
450 debugger->set_exec(exec_name);
451 debugger->set_prefix(
rank);
452 debugger->set_cmd(
"lldb_xterm");
453 debugger->debug(
"start");
virtual void set_cmd(const char *)
virtual void set_prefix(const char *p)
This sets a prefix which preceeds all messages printing by Debugger.
virtual void got_signal(int sig)
Called when signal sig is received. This is mainly for internal use.
static void set_default_debugger(const std::shared_ptr< Debugger > &)
Set the global default debugger. The initial value is null.
static void __traceback(const std::string &prefix, const char *reason=nullptr)
volatile int debugger_ready_
virtual void handle_defaults()
This calls handle(int) with all of the major signals.
virtual void set_wait_for_debugger(int)
virtual void traceback(const char *reason)
static std::shared_ptr< Debugger > default_debugger()
Return the global default debugger.
virtual void default_cmd()
Calls set_cmd with a hopefully suitable default.
virtual void set_exit_on_signal(int)
Turn on or off exit after a signel. The default is on.
virtual void handle(int sig)
The Debugger will be activated when sig is caught.
Debugger(const char *exec=nullptr)
Programmatic construction of Debugger.
virtual void debug(const char *reason)
virtual void release(int sig)
Reverts the effect of handle(sig) , i.e. the Debugger will not be activated when sig is caught.
static std::shared_ptr< Debugger > default_debugger_
virtual void set_debug_on_signal(int)
Turn on or off debugging on a signel. The default is on.
virtual void set_exec(const char *)
virtual void set_traceback_on_signal(int)
Turn on or off traceback on a signel. The default is on.
std::string str(const size_t nframes_to_skip=0) const
top-level TTG namespace contains runtime-neutral functionality
void launch_lldb(int rank, const char *exec_name)
void launch_debugger(int rank, const char *exec_name, const char *cmd)
int rank(World world=default_execution_context())
void initialize_fpe()
Initializes the floating point exceptions.
void launch_gdb(int rank, const char *exec_name)