2020-06-15 14:18:57 +00:00
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
|
|
|
│ any purpose with or without fee is hereby granted, provided that the │
|
|
|
|
│ above copyright notice and this permission notice appear in all copies. │
|
2020-06-15 14:18:57 +00:00
|
|
|
│ │
|
2020-12-28 01:18:44 +00:00
|
|
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
|
|
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
|
|
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
|
|
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
|
|
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
|
|
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
|
|
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
|
|
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
2020-06-15 14:18:57 +00:00
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
2021-09-13 04:04:44 +00:00
|
|
|
#include "libc/bits/weaken.h"
|
2022-04-18 07:01:26 +00:00
|
|
|
#include "libc/calls/calls.h"
|
2022-05-23 22:06:11 +00:00
|
|
|
#include "libc/calls/state.internal.h"
|
2022-04-07 07:15:35 +00:00
|
|
|
#include "libc/calls/strace.internal.h"
|
2021-08-13 18:18:25 +00:00
|
|
|
#include "libc/calls/struct/sigaction.h"
|
2022-06-09 03:01:28 +00:00
|
|
|
#include "libc/calls/struct/utsname.h"
|
2020-11-25 16:19:00 +00:00
|
|
|
#include "libc/errno.h"
|
2021-09-28 05:58:51 +00:00
|
|
|
#include "libc/intrin/asan.internal.h"
|
2022-03-16 20:33:13 +00:00
|
|
|
#include "libc/intrin/kprintf.h"
|
2022-04-12 12:20:17 +00:00
|
|
|
#include "libc/intrin/lockcmpxchg.h"
|
2020-11-25 16:19:00 +00:00
|
|
|
#include "libc/log/backtrace.internal.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
#include "libc/log/gdb.h"
|
|
|
|
#include "libc/log/internal.h"
|
2021-09-28 05:58:51 +00:00
|
|
|
#include "libc/log/libfatal.internal.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
#include "libc/log/log.h"
|
2021-03-01 07:42:35 +00:00
|
|
|
#include "libc/macros.internal.h"
|
2020-09-03 12:44:37 +00:00
|
|
|
#include "libc/nexgen32e/stackframe.h"
|
2022-03-23 13:31:55 +00:00
|
|
|
#include "libc/runtime/internal.h"
|
2021-02-26 02:30:17 +00:00
|
|
|
#include "libc/runtime/pc.internal.h"
|
2022-05-19 23:57:49 +00:00
|
|
|
#include "libc/runtime/runtime.h"
|
2020-06-15 14:18:57 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @fileoverview Abnormal termination handling & GUI debugging.
|
|
|
|
* @see libc/onkill.c
|
|
|
|
*/
|
|
|
|
|
2022-04-15 06:39:48 +00:00
|
|
|
STATIC_YOINK("strerror_wr"); /* for kprintf %m */
|
|
|
|
STATIC_YOINK("strsignal"); /* for kprintf %G */
|
2022-03-16 20:33:13 +00:00
|
|
|
|
2020-12-05 20:20:41 +00:00
|
|
|
static const char kGregOrder[17] forcealign(1) = {
|
2020-08-25 11:23:25 +00:00
|
|
|
13, 11, 8, 14, 12, 9, 10, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7,
|
|
|
|
};
|
|
|
|
|
2020-12-05 20:20:41 +00:00
|
|
|
static const char kGregNames[17][4] forcealign(1) = {
|
2020-06-15 14:18:57 +00:00
|
|
|
"R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", "RDI",
|
2020-08-25 11:23:25 +00:00
|
|
|
"RSI", "RBP", "RBX", "RDX", "RAX", "RCX", "RSP", "RIP",
|
|
|
|
};
|
|
|
|
|
2021-02-26 02:30:17 +00:00
|
|
|
static const char kCpuFlags[12] forcealign(1) = "CVPRAKZSTIDO";
|
|
|
|
static const char kFpuExceptions[6] forcealign(1) = "IDZOUP";
|
2020-06-15 14:18:57 +00:00
|
|
|
|
2022-03-16 20:33:13 +00:00
|
|
|
int kCrashSigs[7];
|
2020-06-15 14:18:57 +00:00
|
|
|
|
2021-10-14 00:27:13 +00:00
|
|
|
relegated static void ShowFunctionCalls(ucontext_t *ctx) {
|
2020-06-15 14:18:57 +00:00
|
|
|
struct StackFrame *bp;
|
|
|
|
struct StackFrame goodframe;
|
2021-10-15 02:36:49 +00:00
|
|
|
if (!ctx->uc_mcontext.rip) {
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("%s is NULL can't show backtrace\n", "RIP");
|
2021-10-15 02:36:49 +00:00
|
|
|
} else {
|
2020-06-15 14:18:57 +00:00
|
|
|
goodframe.next = (struct StackFrame *)ctx->uc_mcontext.rbp;
|
|
|
|
goodframe.addr = ctx->uc_mcontext.rip;
|
|
|
|
bp = &goodframe;
|
2021-10-14 00:27:13 +00:00
|
|
|
ShowBacktrace(2, bp);
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-26 02:30:17 +00:00
|
|
|
relegated static char *AddFlag(char *p, int b, const char *s) {
|
2021-10-14 00:27:13 +00:00
|
|
|
if (b) {
|
|
|
|
p = __stpcpy(p, s);
|
|
|
|
} else {
|
|
|
|
*p = 0;
|
|
|
|
}
|
2021-02-26 02:30:17 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2021-09-28 05:58:51 +00:00
|
|
|
relegated static char *DescribeCpuFlags(char *p, int flags, int x87sw,
|
|
|
|
int mxcsr) {
|
2020-10-11 04:18:53 +00:00
|
|
|
unsigned i;
|
2021-02-26 02:30:17 +00:00
|
|
|
for (i = 0; i < ARRAYLEN(kCpuFlags); ++i) {
|
2020-10-11 04:18:53 +00:00
|
|
|
if (flags & 1) {
|
|
|
|
*p++ = ' ';
|
2021-02-26 02:30:17 +00:00
|
|
|
*p++ = kCpuFlags[i];
|
2020-10-11 04:18:53 +00:00
|
|
|
*p++ = 'F';
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
2020-10-11 04:18:53 +00:00
|
|
|
flags >>= 1;
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
2021-02-26 02:30:17 +00:00
|
|
|
for (i = 0; i < ARRAYLEN(kFpuExceptions); ++i) {
|
|
|
|
if ((x87sw | mxcsr) & (1 << i)) {
|
|
|
|
*p++ = ' ';
|
|
|
|
*p++ = kFpuExceptions[i];
|
|
|
|
*p++ = 'E';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
p = AddFlag(p, x87sw & FPU_SF, " SF");
|
|
|
|
p = AddFlag(p, x87sw & FPU_C0, " C0");
|
|
|
|
p = AddFlag(p, x87sw & FPU_C1, " C1");
|
|
|
|
p = AddFlag(p, x87sw & FPU_C2, " C2");
|
|
|
|
p = AddFlag(p, x87sw & FPU_C3, " C3");
|
2021-09-28 05:58:51 +00:00
|
|
|
return p;
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
|
2021-10-14 00:27:13 +00:00
|
|
|
relegated static void ShowGeneralRegisters(ucontext_t *ctx) {
|
2021-09-28 05:58:51 +00:00
|
|
|
int64_t x;
|
|
|
|
const char *s;
|
2020-06-15 14:18:57 +00:00
|
|
|
size_t i, j, k;
|
|
|
|
long double st;
|
2021-10-14 00:27:13 +00:00
|
|
|
char *p, buf[128];
|
|
|
|
p = buf;
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n");
|
2020-06-15 14:18:57 +00:00
|
|
|
for (i = 0, j = 0, k = 0; i < ARRAYLEN(kGregNames); ++i) {
|
2021-09-28 05:58:51 +00:00
|
|
|
if (j > 0) *p++ = ' ';
|
|
|
|
if (!(s = kGregNames[(unsigned)kGregOrder[i]])[2]) *p++ = ' ';
|
|
|
|
p = __stpcpy(p, s), *p++ = ' ';
|
|
|
|
p = __fixcpy(p, ctx->uc_mcontext.gregs[(unsigned)kGregOrder[i]], 64);
|
2020-06-15 14:18:57 +00:00
|
|
|
if (++j == 3) {
|
|
|
|
j = 0;
|
2021-01-25 21:08:05 +00:00
|
|
|
if (ctx->uc_mcontext.fpregs) {
|
|
|
|
memcpy(&st, (char *)&ctx->uc_mcontext.fpregs->st[k], sizeof(st));
|
|
|
|
} else {
|
2021-09-28 05:58:51 +00:00
|
|
|
bzero(&st, sizeof(st));
|
2021-01-25 21:08:05 +00:00
|
|
|
}
|
2021-09-28 05:58:51 +00:00
|
|
|
p = __stpcpy(p, " ST(");
|
|
|
|
p = __uintcpy(p, k++);
|
|
|
|
p = __stpcpy(p, ") ");
|
|
|
|
x = st * 1000;
|
|
|
|
if (x < 0) x = -x, *p++ = '-';
|
|
|
|
p = __uintcpy(p, x / 1000), *p++ = '.';
|
2022-03-16 20:33:13 +00:00
|
|
|
p = __uintcpy(p, x % 1000);
|
2021-10-14 00:27:13 +00:00
|
|
|
*p = 0;
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("%s\n", buf);
|
2021-10-14 00:27:13 +00:00
|
|
|
p = buf;
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
}
|
2021-10-14 00:27:13 +00:00
|
|
|
DescribeCpuFlags(
|
2022-04-20 16:56:53 +00:00
|
|
|
p, ctx->uc_mcontext.eflags,
|
2021-02-26 02:30:17 +00:00
|
|
|
ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->swd : 0,
|
|
|
|
ctx->uc_mcontext.fpregs ? ctx->uc_mcontext.fpregs->mxcsr : 0);
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("%s\n", buf);
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
|
2021-10-14 00:27:13 +00:00
|
|
|
relegated static void ShowSseRegisters(ucontext_t *ctx) {
|
2020-06-15 14:18:57 +00:00
|
|
|
size_t i;
|
2021-10-14 00:27:13 +00:00
|
|
|
char *p, buf[128];
|
2021-01-25 21:08:05 +00:00
|
|
|
if (ctx->uc_mcontext.fpregs) {
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n");
|
2021-01-25 21:08:05 +00:00
|
|
|
for (i = 0; i < 8; ++i) {
|
2021-10-14 00:27:13 +00:00
|
|
|
p = buf;
|
2021-09-28 05:58:51 +00:00
|
|
|
if (i >= 10) {
|
|
|
|
*p++ = i / 10 + '0';
|
|
|
|
*p++ = i % 10 + '0';
|
|
|
|
} else {
|
|
|
|
*p++ = i + '0';
|
|
|
|
*p++ = ' ';
|
|
|
|
}
|
|
|
|
*p++ = ' ';
|
|
|
|
p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 0].u64[1], 64);
|
|
|
|
p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 0].u64[0], 64);
|
|
|
|
p = __stpcpy(p, " XMM");
|
|
|
|
if (i + 8 >= 10) {
|
|
|
|
*p++ = (i + 8) / 10 + '0';
|
|
|
|
*p++ = (i + 8) % 10 + '0';
|
|
|
|
} else {
|
|
|
|
*p++ = (i + 8) + '0';
|
|
|
|
*p++ = ' ';
|
|
|
|
}
|
|
|
|
*p++ = ' ';
|
|
|
|
p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 8].u64[1], 64);
|
|
|
|
p = __fixcpy(p, ctx->uc_mcontext.fpregs->xmm[i + 8].u64[0], 64);
|
2021-10-14 00:27:13 +00:00
|
|
|
*p = 0;
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("XMM%s\n", buf);
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-13 04:04:44 +00:00
|
|
|
void ShowCrashReportHook(int, int, int, struct siginfo *, ucontext_t *);
|
|
|
|
|
2021-10-14 00:27:13 +00:00
|
|
|
relegated void ShowCrashReport(int err, int sig, struct siginfo *si,
|
2021-09-28 05:58:51 +00:00
|
|
|
ucontext_t *ctx) {
|
2020-11-09 23:41:11 +00:00
|
|
|
int i;
|
2021-09-28 05:58:51 +00:00
|
|
|
char *p;
|
2021-10-14 00:27:13 +00:00
|
|
|
char host[64];
|
2020-06-15 14:18:57 +00:00
|
|
|
struct utsname names;
|
2021-09-28 05:58:51 +00:00
|
|
|
static char buf[4096];
|
2021-09-13 04:04:44 +00:00
|
|
|
if (weaken(ShowCrashReportHook)) {
|
2021-10-14 00:27:13 +00:00
|
|
|
ShowCrashReportHook(2, err, sig, si, ctx);
|
2021-09-13 04:04:44 +00:00
|
|
|
}
|
2022-03-16 20:33:13 +00:00
|
|
|
names.sysname[0] = 0;
|
|
|
|
names.release[0] = 0;
|
|
|
|
names.version[0] = 0;
|
|
|
|
names.nodename[0] = 0;
|
2021-10-14 00:27:13 +00:00
|
|
|
__stpcpy(host, "unknown");
|
2022-04-18 15:54:42 +00:00
|
|
|
gethostname(host, sizeof(host));
|
|
|
|
uname(&names);
|
2021-09-28 05:58:51 +00:00
|
|
|
p = buf;
|
2022-03-16 20:33:13 +00:00
|
|
|
errno = err;
|
2022-05-12 13:43:59 +00:00
|
|
|
kprintf("\n%serror%s: Uncaught %G (%s) on %s pid %d tid %d\n"
|
2022-04-24 16:59:22 +00:00
|
|
|
" %s\n"
|
|
|
|
" %m\n"
|
|
|
|
" %s %s %s %s\n",
|
2022-04-12 15:05:22 +00:00
|
|
|
!__nocolor ? "\e[30;101m" : "", !__nocolor ? "\e[0m" : "", sig,
|
2022-05-18 23:41:29 +00:00
|
|
|
(ctx &&
|
|
|
|
(ctx->uc_mcontext.rsp >= (intptr_t)GetStaticStackAddr(0) &&
|
|
|
|
ctx->uc_mcontext.rsp <= (intptr_t)GetStaticStackAddr(0) + PAGESIZE))
|
2022-03-16 20:33:13 +00:00
|
|
|
? "Stack Overflow"
|
|
|
|
: GetSiCodeName(sig, si->si_code),
|
2022-05-12 13:43:59 +00:00
|
|
|
host, getpid(), gettid(), program_invocation_name, names.sysname,
|
|
|
|
names.version, names.nodename, names.release);
|
2020-06-15 14:18:57 +00:00
|
|
|
if (ctx) {
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n");
|
2021-10-14 00:27:13 +00:00
|
|
|
ShowFunctionCalls(ctx);
|
|
|
|
ShowGeneralRegisters(ctx);
|
|
|
|
ShowSseRegisters(ctx);
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n");
|
2022-05-19 23:57:49 +00:00
|
|
|
__print_maps();
|
2021-10-14 00:27:13 +00:00
|
|
|
/* PrintSystemMappings(2); */
|
2021-09-28 05:58:51 +00:00
|
|
|
if (__argv) {
|
|
|
|
for (i = 0; i < __argc; ++i) {
|
|
|
|
if (!__argv[i]) continue;
|
|
|
|
if (IsAsan() && !__asan_is_valid(__argv[i], 1)) continue;
|
2022-03-16 20:33:13 +00:00
|
|
|
kprintf("%s ", __argv[i]);
|
2021-09-28 05:58:51 +00:00
|
|
|
}
|
2020-11-09 23:41:11 +00:00
|
|
|
}
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n");
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
|
|
|
|
2022-03-18 09:33:37 +00:00
|
|
|
static wontreturn relegated noinstrument void __minicrash(int sig,
|
|
|
|
struct siginfo *si,
|
|
|
|
ucontext_t *ctx,
|
|
|
|
const char *kind) {
|
2022-04-24 16:59:22 +00:00
|
|
|
kprintf("\n"
|
|
|
|
"\n"
|
|
|
|
"CRASHED %s WITH %G\n"
|
|
|
|
"%s\n"
|
|
|
|
"RIP %x\n"
|
|
|
|
"RSP %x\n"
|
|
|
|
"RBP %x\n"
|
|
|
|
"\n",
|
2022-04-12 15:05:22 +00:00
|
|
|
kind, sig, __argv[0], ctx ? ctx->uc_mcontext.rip : 0,
|
2022-03-16 20:33:13 +00:00
|
|
|
ctx ? ctx->uc_mcontext.rsp : 0, ctx ? ctx->uc_mcontext.rbp : 0);
|
2022-03-23 13:31:55 +00:00
|
|
|
__restorewintty();
|
|
|
|
_Exit(119);
|
2022-03-16 20:33:13 +00:00
|
|
|
}
|
|
|
|
|
2020-06-15 14:18:57 +00:00
|
|
|
/**
|
|
|
|
* Crashes in a developer-friendly human-centric way.
|
|
|
|
*
|
|
|
|
* We first try to launch GDB if it's an interactive development
|
|
|
|
* session. Otherwise we show a really good crash report, sort of like
|
|
|
|
* Python, that includes filenames and line numbers. Many editors, e.g.
|
|
|
|
* Emacs, will even recognize its syntax for quick hopping to the
|
|
|
|
* failing line. That's only possible if the the .com.dbg file is in the
|
|
|
|
* same folder. If the concomitant debug binary can't be found, we
|
|
|
|
* simply print addresses which may be cross-referenced using objdump.
|
|
|
|
*
|
|
|
|
* This function never returns, except for traps w/ human supervision.
|
|
|
|
*/
|
2022-03-18 09:33:37 +00:00
|
|
|
relegated noinstrument void __oncrash(int sig, struct siginfo *si,
|
|
|
|
ucontext_t *ctx) {
|
2020-06-15 14:18:57 +00:00
|
|
|
intptr_t rip;
|
2022-05-14 11:33:58 +00:00
|
|
|
int gdbpid, err;
|
2021-10-14 00:27:13 +00:00
|
|
|
static bool noreentry, notpossible;
|
2022-05-16 20:20:08 +00:00
|
|
|
STRACE("__oncrash rip %x", ctx->uc_mcontext.rip);
|
2022-05-18 23:41:29 +00:00
|
|
|
--__ftrace;
|
|
|
|
--__strace;
|
2022-04-12 12:20:17 +00:00
|
|
|
if (_lockcmpxchg(&noreentry, false, true)) {
|
2022-03-16 20:33:13 +00:00
|
|
|
if (!__vforked) {
|
|
|
|
rip = ctx ? ctx->uc_mcontext.rip : 0;
|
|
|
|
err = errno;
|
|
|
|
if ((gdbpid = IsDebuggerPresent(true))) {
|
|
|
|
DebugBreak();
|
2022-03-18 09:33:37 +00:00
|
|
|
} else if (__nocolor || g_isrunningundermake) {
|
2022-03-16 20:33:13 +00:00
|
|
|
gdbpid = -1;
|
2022-04-18 15:54:42 +00:00
|
|
|
} else if (!IsTiny() && IsLinux() && FindDebugBinary() && !__isworker) {
|
2022-03-16 20:33:13 +00:00
|
|
|
RestoreDefaultCrashSignalHandlers();
|
|
|
|
gdbpid = AttachDebugger(
|
|
|
|
((sig == SIGTRAP || sig == SIGQUIT) &&
|
|
|
|
(rip >= (intptr_t)&_base && rip < (intptr_t)&_etext))
|
|
|
|
? rip
|
|
|
|
: 0);
|
|
|
|
}
|
|
|
|
if (!(gdbpid > 0 && (sig == SIGTRAP || sig == SIGQUIT))) {
|
2022-04-23 01:55:28 +00:00
|
|
|
__restore_tty();
|
2022-03-16 20:33:13 +00:00
|
|
|
ShowCrashReport(err, sig, si, ctx);
|
2022-03-23 13:31:55 +00:00
|
|
|
__restorewintty();
|
2022-03-20 15:01:14 +00:00
|
|
|
_Exit(128 + sig);
|
2022-03-16 20:33:13 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
__minicrash(sig, si, ctx, "WHILE VFORKED");
|
2021-10-14 00:27:13 +00:00
|
|
|
}
|
2022-03-16 20:33:13 +00:00
|
|
|
} else if (sig == SIGTRAP) {
|
|
|
|
/* chances are IsDebuggerPresent() confused strace w/ gdb */
|
2022-05-14 11:33:58 +00:00
|
|
|
goto ItsATrap;
|
2022-04-12 12:20:17 +00:00
|
|
|
} else if (_lockcmpxchg(¬possible, false, true)) {
|
2022-03-16 20:33:13 +00:00
|
|
|
__minicrash(sig, si, ctx, "WHILE CRASHING");
|
2021-10-14 00:27:13 +00:00
|
|
|
} else {
|
|
|
|
for (;;) {
|
|
|
|
asm("ud2");
|
|
|
|
}
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|
2021-10-14 00:27:13 +00:00
|
|
|
noreentry = false;
|
2022-05-14 11:33:58 +00:00
|
|
|
ItsATrap:
|
2022-05-18 23:41:29 +00:00
|
|
|
++__strace;
|
|
|
|
++__ftrace;
|
2020-06-15 14:18:57 +00:00
|
|
|
}
|