xref: /netbsd-src/external/gpl3/gdb.old/dist/gdbsupport/alt-stack.h (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
17d62b00eSchristos /* Temporarily install an alternate signal stack
27d62b00eSchristos 
3*6881a400Schristos    Copyright (C) 2019-2023 Free Software Foundation, Inc.
47d62b00eSchristos 
57d62b00eSchristos    This file is part of GDB.
67d62b00eSchristos 
77d62b00eSchristos    This program is free software; you can redistribute it and/or modify
87d62b00eSchristos    it under the terms of the GNU General Public License as published by
97d62b00eSchristos    the Free Software Foundation; either version 3 of the License, or
107d62b00eSchristos    (at your option) any later version.
117d62b00eSchristos 
127d62b00eSchristos    This program is distributed in the hope that it will be useful,
137d62b00eSchristos    but WITHOUT ANY WARRANTY; without even the implied warranty of
147d62b00eSchristos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
157d62b00eSchristos    GNU General Public License for more details.
167d62b00eSchristos 
177d62b00eSchristos    You should have received a copy of the GNU General Public License
187d62b00eSchristos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
197d62b00eSchristos 
207d62b00eSchristos #ifndef GDBSUPPORT_ALT_STACK_H
217d62b00eSchristos #define GDBSUPPORT_ALT_STACK_H
227d62b00eSchristos 
237d62b00eSchristos #include <signal.h>
247d62b00eSchristos 
257d62b00eSchristos namespace gdb
267d62b00eSchristos {
277d62b00eSchristos 
287d62b00eSchristos /* Try to set up an alternate signal stack for SIGSEGV handlers.
297d62b00eSchristos    This allows us to handle SIGSEGV signals generated when the
307d62b00eSchristos    normal process stack is exhausted.  If this stack is not set
317d62b00eSchristos    up (sigaltstack is unavailable or fails) and a SIGSEGV is
327d62b00eSchristos    generated when the normal stack is exhausted then the program
337d62b00eSchristos    will behave as though no SIGSEGV handler was installed.  */
347d62b00eSchristos class alternate_signal_stack
357d62b00eSchristos {
367d62b00eSchristos public:
377d62b00eSchristos   alternate_signal_stack ()
387d62b00eSchristos   {
397d62b00eSchristos #ifdef HAVE_SIGALTSTACK
407d62b00eSchristos     m_stack.reset ((char *) xmalloc (SIGSTKSZ));
417d62b00eSchristos 
427d62b00eSchristos     stack_t stack;
437d62b00eSchristos     stack.ss_sp = m_stack.get ();
447d62b00eSchristos     stack.ss_size = SIGSTKSZ;
457d62b00eSchristos     stack.ss_flags = 0;
467d62b00eSchristos 
477d62b00eSchristos     sigaltstack (&stack, &m_old_stack);
487d62b00eSchristos #endif
497d62b00eSchristos   }
507d62b00eSchristos 
517d62b00eSchristos   ~alternate_signal_stack ()
527d62b00eSchristos   {
537d62b00eSchristos #ifdef HAVE_SIGALTSTACK
547d62b00eSchristos     sigaltstack (&m_old_stack, nullptr);
557d62b00eSchristos #endif
567d62b00eSchristos   }
577d62b00eSchristos 
587d62b00eSchristos   DISABLE_COPY_AND_ASSIGN (alternate_signal_stack);
597d62b00eSchristos 
607d62b00eSchristos private:
617d62b00eSchristos 
627d62b00eSchristos #ifdef HAVE_SIGALTSTACK
637d62b00eSchristos   gdb::unique_xmalloc_ptr<char> m_stack;
647d62b00eSchristos   stack_t m_old_stack;
657d62b00eSchristos #endif
667d62b00eSchristos };
677d62b00eSchristos 
687d62b00eSchristos }
697d62b00eSchristos 
707d62b00eSchristos #endif /* GDBSUPPORT_ALT_STACK_H */
71