44# include <sys/resource.h>
45# if HAVE_BACKTRACE_SYMBOLS_FD
57# if defined __KCC && defined __sgi
58# include </usr/include/exception.h>
60# include <exception.h>
68# if HAVE_RLD_INTERFACE_H
69# include <rld_interface.h>
74# if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
81# define STDERR_HANDLE GetStdHandle (STD_ERROR_HANDLE)
83# define STDERR_HANDLE STDERR_FILENO
90# define MYWRITE(fd,data,n) do { DWORD written; WriteFile(fd,data,n,\
91 &written,0); } while (0)
93# define MYWRITE(fd,data,n) write(fd,data,n)
97# define MYWRITELIT(fd,str) MYWRITE(fd,str,sizeof(str)-1)
103#if HAVE_BACKTRACE_SYMBOLS_FD
106static const int MAX_BACKTRACE_DEPTH = 128;
110#if HAVE_BACKTRACE_SYMBOLS_FD && HAVE_DLADDR
117std::string addr2LinePath =
"/usr/bin/eu-addr2line";
127 backtrace (trace, 1);
129 if (access (addr2LinePath.c_str(), F_OK) == 0) {
134 std::string path = getenv (
"PATH");
135 while (!path.empty()) {
136 std::string::size_type pos = path.find (
':');
137 std::string dir = path.substr (0, pos);
138 if (pos != std::string::npos) ++pos;
142 std::string p1 = dir +
"/eu-addr2line";
143 if (access (p1.c_str(), F_OK) == 0) {
144 addr2LinePath = std::move (p1);
150 std::string p2 = dir +
"/addr2line";
151 if (access (p2.c_str(), F_OK) == 0) {
152 addr2LinePath = std::move (p2);
159BacktraceInit backtraceInit;
165int stacktracePopenFD (
const char* cmd,
pid_t& child_pid)
173 if (stat < 0)
return stat;
175 int parent_end = fds[0];
176 int child_end = fds[1];
190 if (child_pid == 0) {
191 int child_std_end = 1;
193 if (child_end != child_std_end) {
194 dup2 (child_end, child_std_end);
204 execl (
"/bin/sh",
"sh",
"-c", cmd, (
char *) 0);
218int stacktracePcloseFD (
int fd,
pid_t child_pid)
220 int stat = close (fd);
221 if (stat < 0)
return stat;
230 wait_pid = waitpid (child_pid, &wstatus, 0);
231 }
while (wait_pid == -1 && errno == EINTR);
239int stacktraceReadline (
int fd,
char* buf,
int buflen)
242 while (len < buflen-1) {
243 int stat =
read (fd, buf, 1);
244 if (stat < 0)
return stat;
245 if (stat == 0)
break;
246 if (*buf ==
'\n')
break;
290GetLogicalAddress (PVOID addr, PTSTR name, DWORD
length,
293 MEMORY_BASIC_INFORMATION
info;
295 if (! VirtualQuery (addr, &info,
sizeof (info)))
299 if (! GetModuleFileName ((HMODULE) module, name,
length))
302 PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER) module;
303 PIMAGE_NT_HEADERS ntheader
304 = (PIMAGE_NT_HEADERS) (module + dosheader->e_lfanew);
305 PIMAGE_SECTION_HEADER sect = IMAGE_FIRST_SECTION (ntheader);
306 DWORD rva = (DWORD) addr - module;
308 for (
unsigned i = 0;
i < ntheader->FileHeader.NumberOfSections; ++
i,++sect)
310 DWORD sect_start = sect->VirtualAddress;
311 DWORD sect_end = sect_start + std::max (sect->SizeOfRawData,
312 sect->Misc.VirtualSize);
314 if ((rva >= sect_start) && (rva <= sect_end))
317 offset = rva - sect_start;
338 char addrbuf [addrbuf_size];
340#if HAVE_BACKTRACE_SYMBOLS_FD && HAVE_DLADDR
342 char diffbuf [diffbuf_size];
343 static const char trailer [] =
"]\n";
346 char dembuf[ LINE_MAX ];
347 char line[ LINE_MAX ];
349 char relbuf [relbuf_size];
351 if (dladdr ((
void*)addr, &info) && info.dli_fname && info.dli_fname[0])
353 const char *libname = info.dli_fname;
355 unsigned long symaddr = (
unsigned long) info.dli_saddr;
356 bool gte = (addr >= symaddr);
357 unsigned long diff = (gte ? addr - symaddr : symaddr - addr);
363 unsigned long libaddr = (
unsigned long) info.dli_fbase;
364 unsigned long relative_address = (addr >= libaddr) ? addr - libaddr : libaddr - addr;
374 if (strstr (info.dli_fname,
".so") == 0 && libaddr == 0x400000)
375 relative_address = addr;
380 const char* symname = dembuf;
384 size_t len = strlen(info.dli_fname);
385 if ( len > 0 && len + 80 < LINE_MAX)
387 if (getenv (
"LD_PRELOAD"))
388 unsetenv (
"LD_PRELOAD");
390 if ( addr2LinePath ==
"/usr/bin/eu-addr2line" )
392 snprintf (line, LINE_MAX,
"%s -f -e %s %p | /usr/bin/c++filt | /usr/bin/tr \\\\012 \\\\040 ",
393 addr2LinePath.c_str(),
395 (
void*)relative_address);
399 snprintf (line, LINE_MAX,
"%s -f -C -e %s %p",
400 addr2LinePath.c_str(),
402 (
void*)relative_address);
405 pfd = stacktracePopenFD( line, child_pid );
413 demlen = stacktraceReadline (pfd, dembuf,
sizeof(dembuf));
415 length = stacktraceReadline (pfd, line+1,
sizeof(line)-1);
418 int stat = stacktracePcloseFD (pfd, child_pid);
421 if ( stat || line[1] ==
'?' ||
length < 0)
427 if ( stat || demlen <= 0 || dembuf[0] ==
'?') {
428 symname = info.dli_sname;
429 if (!symname) symname =
"???";
430 demlen = strlen (symname);
437 bufs [nbufs].iov_base = addrbuf;
438 bufs [nbufs].iov_len = snprintf (addrbuf, addrbuf_size,
" 0x%08lx ", addr);
441 bufs [nbufs].iov_base = (
void *) symname;
442 bufs [nbufs].iov_len = demlen;
446 bufs [nbufs].iov_base = line;
447 bufs [nbufs].iov_len =
length;
451 bufs [nbufs].iov_base = diffbuf;
452 bufs [nbufs].iov_len = snprintf (diffbuf, diffbuf_size,
" %c 0x%lx [",
453 gte ?
'+' :
'-',
diff);
456 bufs [nbufs].iov_base = (
void *) libname;
457 bufs [nbufs].iov_len = strlen (libname);
461 bufs [nbufs].iov_base = relbuf;
462 bufs [nbufs].iov_len = snprintf( relbuf, relbuf_size,
" D[%p]", (
void*)relative_address );
466 bufs [nbufs].iov_base = (
void *) trailer;
467 bufs [nbufs].iov_len = 2;
474 bufs [nbufs].iov_base = addrbuf;
475 bufs [nbufs].iov_len = snprintf (addrbuf, addrbuf_size,
" 0x%08lx ", addr);
478 bufs [nbufs].iov_base = (
void *)
"<unknown function>\n";
479 bufs [nbufs].iov_len = 19;
483 writev (fd, bufs, nbufs);
487#if !(HAVE_BACKTRACE_SYMBOLS_FD && HAVE_DLADDR) && __GNUC__ >=4
489 typedef unsigned _Unwind_Ptr
__attribute__((__mode__(__pointer__)));
490 struct _Unwind_Context;
494 _URC_FOREIGN_EXCEPTION_CAUGHT = 1,
495 _URC_FATAL_PHASE2_ERROR = 2,
496 _URC_FATAL_PHASE1_ERROR = 3,
497 _URC_NORMAL_STOP = 4,
498 _URC_END_OF_STACK = 5,
499 _URC_HANDLER_FOUND = 6,
500 _URC_INSTALL_CONTEXT = 7,
501 _URC_CONTINUE_UNWIND = 8
502 } _Unwind_Reason_Code;
503 typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (_Unwind_Context *,
void *);
504 extern _Unwind_Reason_Code _Unwind_Backtrace (_Unwind_Trace_Fn,
void *);
505 extern _Unwind_Ptr _Unwind_GetIP (_Unwind_Context *);
506 extern _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *);
516unwindWalkStack (_Unwind_Context *ctx,
void *
data)
522 char addrbuf [addrbuf_size];
524 char diffbuf [diffbuf_size];
525 static const char trailer [] =
"]\n";
526 unsigned long ip = _Unwind_GetIP (ctx);
527 unsigned long ir = _Unwind_GetRegionStart (ctx);
531 if (dladdr ((
void *)
ir, &info) &&
info.dli_fname &&
info.dli_fname[0])
533 const char *libname =
info.dli_fname;
534 const char *symname = (
info.dli_sname &&
info.dli_sname[0]
535 ?
info.dli_sname :
"?");
536 unsigned long symaddr = (
unsigned long)
info.dli_saddr;
537 bool gte = (
ip >= symaddr);
538 unsigned long diff = (gte ?
ip - symaddr : symaddr -
ip);
540 bufs [nbufs].iov_base = addrbuf;
541 bufs [nbufs].iov_len = snprintf (addrbuf, addrbuf_size,
" 0x%08lx ", ip);
544 bufs [nbufs].iov_base = (
char *) symname;
545 bufs [nbufs].iov_len = strlen (symname);
548 bufs [nbufs].iov_base = diffbuf;
549 bufs [nbufs].iov_len = snprintf (diffbuf, diffbuf_size,
" %s 0x%lx [",
550 gte ?
"+" :
"-",
diff);
553 bufs [nbufs].iov_base = (
char *) libname;
554 bufs [nbufs].iov_len = strlen (libname);
557 bufs [nbufs].iov_base = (
char *) trailer;
558 bufs [nbufs].iov_len = 2;
564 bufs [nbufs].iov_base = addrbuf;
565 bufs [nbufs].iov_len = snprintf (addrbuf, addrbuf_size,
" 0x%08lx ", ip);
568 bufs [nbufs].iov_base = diffbuf;
569 bufs [nbufs].iov_len = snprintf (diffbuf, diffbuf_size,
" <?%08lx> + 0x%lx\n",
574 writev (fd, bufs, nbufs);
575 return _URC_NO_REASON;
584 addr2LinePath = path;
588#if HAVE_U_STACK_TRACE
590extern "C" void U_STACK_TRACE (
void);
595extern "C" void xl__trbk (
void);
648 if (! SymInitialize (GetCurrentProcess (), NULL, TRUE))
650 MYWRITELIT (fd, (
"failed to dump stack trace:"
651 " cannot get symbolic information\n"));
657 BYTE buffer [
sizeof (IMAGEHLP_SYMBOL) + 512 ];
664 IMAGEHLP_MODULE module;
665 char modulename [MAX_PATH];
668 const int buf_size = 2*40+6;
674 context.ContextFlags = CONTEXT_FULL;
675 if (! GetThreadContext (GetCurrentThread (), &context))
683 memset (&module, 0,
sizeof (module));
684 memset (&frame, 0,
sizeof (frame));
686 module.SizeOfStruct = sizeof (module);
688 frame.AddrPC.Offset = context.Eip;
689 frame.AddrPC.Mode = AddrModeFlat;
690 frame.AddrStack.Offset = context.Esp;
691 frame.AddrStack.Mode = AddrModeFlat;
692 frame.AddrFrame.Offset = context.Ebp;
693 frame.AddrFrame.Mode = AddrModeFlat;
697 if (! StackWalk (IMAGE_FILE_MACHINE_I386,
698 GetCurrentProcess (),
703 SymFunctionTableAccess,
706 || frame.AddrFrame.Offset == 0)
715 MYWRITE (fd, buf, snprintf (buf, buf_size,
"(%2u) 0x%08lx 0x%08lx ",
716 level, frame.AddrPC.Offset,
717 frame.AddrFrame.Offset));
719 memset (&symbol, 0,
sizeof (symbol));
720 symbol.sym.SizeOfStruct =
sizeof (symbol);
721 symbol.sym.MaxNameLength =
sizeof (symbol) -
sizeof (symbol.sym);
724 if (SymGetSymFromAddr (GetCurrentProcess (), frame.AddrPC.Offset,
725 &offset, &symbol.sym))
735 MYWRITE (fd, symbol.sym.Name, STDC::strlen (symbol.sym.Name));
736 MYWRITE (fd, buf, snprintf (buf, buf_size,
" + %lx", offset));
738 if (SymGetModuleInfo (GetCurrentProcess(), frame.AddrPC.Offset,
743 STDC::strlen (module.ImageName));
749 GetLogicalAddress ((PVOID) frame.AddrPC.Offset,
750 modulename, sizeof (modulename),
752 MYWRITE (fd, buf, snprintf (buf, buf_size,
"%04lx:%08lx [",
section, offset));
753 MYWRITE (fd, modulename, STDC::strlen (modulename));
759 SymCleanup (GetCurrentProcess ());
761#elif (HAVE_U_STACK_TRACE || HAVE_XL_TRBK)
763 int stderrfd = dup (STDERR_FILENO);
767 int newfd = dup2 (fd, STDERR_FILENO);
774# if HAVE_U_STACK_TRACE
779# error "oops, you shouldn't have gotten here!"
783 dup2 (stderrfd, STDERR_FILENO);
785#elif HAVE_LINUX_UNWIND_BACKTRACE
786 CxxUtils::backtraceByUnwind (stacktraceLine, fd);
788#elif HAVE_BACKTRACE_SYMBOLS_FD && HAVE_DLADDR
791 void *trace [MAX_BACKTRACE_DEPTH];
792 int depth = backtrace (trace, MAX_BACKTRACE_DEPTH);
794 for (
int n = 0; n <
depth; ++n)
796 unsigned long addr = (
unsigned long) trace [n];
797 stacktraceLine (fd, addr);
800#elif HAVE_EXCPT_H && HAVE_PDSC_H && HAVE_RLD_INTERFACE_H
806 char buffer [buffer_size];
810 exc_capture_context (&context);
811 while (!rc && context.sc_pc)
814 pdsc_crd *func, *
base, *crd
815 = exc_remote_lookup_function_entry(0, 0, context.sc_pc, 0, &func, &
base);
816 Elf32_Addr addr = PDSC_CRD_BEGIN_ADDRESS(
base, func);
818 const char *name =
"<unknown function>";
819 snprintf (buffer, buffer_size,
" 0x%012lx %.100s + 0x%lx\n",
820 context.sc_pc, name, context.sc_pc - addr);
821 write (fd, buffer, STDC::strlen(buffer));
822 rc = exc_virtual_unwind(0, &context);
825#elif HAVE_EXCEPTION_H && defined __sgi
834 exc_setjmp (&context);
835 while (context.sc_pc >= 4)
844 const char *libname = 0;
845 const char *symname = 0;
846 Elf32_Addr offset = ~0L;
849 Elf32_Addr pc = context.sc_pc;
850 Dwarf_Fde fde = find_fde_name (&pc, &name);
851 Dwarf_Addr low_pc = context.sc_pc;
852 Dwarf_Unsigned udummy;
861 if (dwarf_get_fde_range (fde, &low_pc, &udummy, &pdummy, &udummy,
862 &odummy, &sdummy, &odummy, &err) == DW_DLV_OK)
863 offset = context.sc_pc - low_pc;
872 Elf32_Addr addr = context.sc_pc;
875 if (_rld_new_interface (_RLD_DLADDR, addr, &info))
877 if (info.dli_fname && info.dli_fname [0])
878 libname = info.dli_fname;
880 Elf32_Addr symaddr = (Elf32_Addr) info.dli_saddr;
881 if (symaddr == low_pc)
882 offset = addr - symaddr;
883 else if (info.dli_sname
884 && info.dli_sname [0]
885 && addr - symaddr < offset)
887 offset = addr - symaddr;
888 symname = info.dli_sname;
893 if (libname && symname)
894 write (fd, buffer, snprintf
895 (buffer, buffer_size,
" 0x%012lx %.100s + 0x%lx [%.200s]\n",
896 addr, symname, offset, libname));
898 write (fd, buffer, snprintf
899 (buffer, buffer_size,
" 0x%012lx %.100s + 0x%lx\n",
900 addr, symname, offset));
902 write (fd, buffer, snprintf
903 (buffer, buffer_size,
" 0x%012lx <unknown function>\n", addr));
917 if (pc != context.sc_pc)
920 exc_unwind (&context, fde);
923#elif defined PROG_PSTACK
925# define CXXFILTER " | " PROG_CXXFILT
932 char buffer [buffer_size];
933 snprintf (buffer, buffer_size,
"%s %lu%s 1>&%d", PROG_PSTACK, (
unsigned long) getpid (),
938#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
940 _Unwind_Backtrace (unwindWalkStack, &fd);
985 if ((corepid = ::fork ()) == 0)
1010 else if (corepid > 0) {
1013 wait_pid = ::waitpid (corepid, &status, 0);
1014 }
while (wait_pid == -1 && errno == EINTR);
1032 struct rlimit core_limit;
1033 getrlimit(RLIMIT_CORE, &core_limit);
1035 unsigned long old_limit = core_limit.rlim_cur;
1036 core_limit.rlim_cur = core_limit.rlim_max;
1037 if ( setrlimit(RLIMIT_CORE, &core_limit) == 0 ) {
1038 return core_limit.rlim_cur;
1052 struct rlimit core_limit;
1053 core_limit.rlim_cur = 0;
1054 core_limit.rlim_max = 0;
1055 setrlimit(RLIMIT_CORE, &core_limit);
Hacked backtrace that can go past a bad stack frame.
char data[hepevt_bytes_allocation_ATLAS]
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Collecting a few shared bits and pieces from SEAL headers.
#define IOFD_INVALID
Invalid channel descriptor constant.
int IOFD
Type the system uses for channel descriptors.
This are the SEAL debug aids, adapted to build in Atlas, after the drop of that project.
#define MYWRITE(fd, data, n)
This is the signal handler from SEAL, adapted to build in Atlas, after the drop of that project.
__attribute__((always_inline)) inline uint16_t TileCalibDrawerBase
Define macros for attributes used to control the static checker.
#define ATLAS_NOT_THREAD_SAFE
getNoisyStrip() Find noisy strips from hitmaps and write out into xml/db formats
static IOFD stacktraceFd(IOFD fd=IOFD_INVALID)
Set and return the file descriptor for stack trace output.
static void coredump(int sig,...)
Drop a core dump and continue.
static std::atomic< IOFD > s_stackTraceFd
The default output file descriptor for stacktrace().
static unsigned long enableCoreFiles()
Try to enable core dump files by raising the soft size limit to the hard limit.
static void disableCoreFiles()
Disable core dump files by setting the soft limit to 0.
static int raise(int sig)
Raise the signal number sig.
static void block(int sig, bool sense)
Block or unblock the signal number sig.
static HandlerType handle(int sig, HandlerType handler, const sigset_t *blockMask=0)
Install a new signal handler handler for signal number sig and returns the old handler.
void(* HandlerType)(int sig, siginfo_t *info, void *extra)
Signal handler type.
#define MYWRITELIT(fd, str)
int ir
counter of the current depth
std::string depth
tag string for intendation
Some weak symbol referencing magic... These are declared in AthenaKernel/getMessageSvc....
StatusCode ROOTMessageFilterSvc::initialize ATLAS_NOT_THREAD_SAFE()
Return the file descriptor fataldump() uses for output.
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)