[webkit-dev] WTFCrash()

2018-03-06 Thread Michael Catanzaro

Hi,

After [1], WTFCrash() is used only in debug builds on Darwin. For 
Darwin release builds, inline assembly is used to trigger a SIGTRAP. I 
experimented with this today and found it works quite badly on Linux, 
somehow confusing gdb and clobbering the top frames of the stacktrace, 
so I think we should leave that unchanged and keep it Darwin-only. So 
this mail applies only to debug builds on Darwin, and to non-Darwin 
ports.


Now, currently, WTFCrash() does three things:

(1) Calls a user-configurable crash hook
(2) Print a low-quality backtrace to stderr
(3) Crash somehow:
  - If ASAN is used, with __builtin_trap() (that's SIGILL on Linux 
x86_64)
  - Then with *(int *)(uintptr_t)0xbbadbeef = 0, which might fail to 
crash if 0xbadbeef is a valid address, and is SIGSEGV otherwise

  - Then with __builtin_trap() if COMPILER(GCC_OR_CLANG)
  - Then with ((void(*)())0)() otherwise (presumably SIGSEGV or 
SIGBUS, dunno)


This is all rather more complicated than it needs to be.

First off, the crash hook is (almost) unused and should simply be 
removed, see [2].


Next, the low-quality backtrace. Does anyone think this is useful? It's 
mainly annoying to me, because it's not anywhere near as good as a 
proper backtrace that shows stack members, it's mangled so function 
names are unnecessarily-difficult to read, and it takes all of five 
seconds to get a much nicer one with modern Linux developer tools. If 
other developers like it, perhaps we could keep it for debug builds 
only, and skip right to the crashing in release builds? I suppose we 
could keep printing it always if there is desire to do this, because it 
has never caused any problems with Linux crash telemetry and doesn't 
seem to be harming anything, but otherwise my instinct is to simplify.


Now, as for how exactly to crash. Current logic, with asan disabled, 
prefers SIGSEGV, then SIGILL if that fails, then SIGSEGV again. I don't 
like that WTFCrash() triggers a SIGSEGV. This is not very clean; at 
least on Linux, it's conventional for assertion failures and other 
intentional crashes to cause SIGABRT instead of trying to write to 
0xbadbeef. SIGILL is also quite unusual. I  think I'd be happy if we 
replace all of WTFCrash() with a single call to abort(). Any objections 
to this? Is there a special reason for the current convoluted logic?


Michael

[1] https://bugs.webkit.org/show_bug.cgi?id=153996
[2] https://bugs.webkit.org/show_bug.cgi?id=183369

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev


Re: [webkit-dev] WTFCrash()

2018-03-06 Thread Mark Lam


> On Mar 6, 2018, at 9:09 PM, Michael Catanzaro  wrote:
> 
> Hi,
> 
> After [1], WTFCrash() is used only in debug builds on Darwin. For Darwin 
> release builds, inline assembly is used to trigger a SIGTRAP. I experimented 
> with this today and found it works quite badly on Linux, somehow confusing 
> gdb and clobbering the top frames of the stacktrace, so I think we should 
> leave that unchanged and keep it Darwin-only. So this mail applies only to 
> debug builds on Darwin, and to non-Darwin ports.
> 
> Now, currently, WTFCrash() does three things:
> 
> (1) Calls a user-configurable crash hook
> (2) Print a low-quality backtrace to stderr
> (3) Crash somehow:
>  - If ASAN is used, with __builtin_trap() (that's SIGILL on Linux x86_64)
>  - Then with *(int *)(uintptr_t)0xbbadbeef = 0, which might fail to crash if 
> 0xbadbeef is a valid address, and is SIGSEGV otherwise
>  - Then with __builtin_trap() if COMPILER(GCC_OR_CLANG)
>  - Then with ((void(*)())0)() otherwise (presumably SIGSEGV or SIGBUS, dunno)
> 
> This is all rather more complicated than it needs to be.
> 
> First off, the crash hook is (almost) unused and should simply be removed, 
> see [2].
> 
> Next, the low-quality backtrace. Does anyone think this is useful? It's 
> mainly annoying to me, because it's not anywhere near as good as a proper 
> backtrace that shows stack members, it's mangled so function names are 
> unnecessarily-difficult to read, and it takes all of five seconds to get a 
> much nicer one with modern Linux developer tools. If other developers like 
> it, perhaps we could keep it for debug builds only, and skip right to the 
> crashing in release builds? I suppose we could keep printing it always if 
> there is desire to do this, because it has never caused any problems with 
> Linux crash telemetry and doesn't seem to be harming anything, but otherwise 
> my instinct is to simplify.

On Darwin, we currently only use WTFCrash() on Debug builds (see definition of 
the CRASH() macro).  Feel free to make linux do the same.  FWIW, I use this 
crash trace a lot when debugging crashes when I don’t already have a debugger 
attached yet.  Of course, with a debugger attached, it is of less value.

> Now, as for how exactly to crash. Current logic, with asan disabled, prefers 
> SIGSEGV, then SIGILL if that fails, then SIGSEGV again. I don't like that 
> WTFCrash() triggers a SIGSEGV. This is not very clean; at least on Linux, 
> it's conventional for assertion failures and other intentional crashes to 
> cause SIGABRT instead of trying to write to 0xbadbeef. SIGILL is also quite 
> unusual. I  think I'd be happy if we replace all of WTFCrash() with a single 
> call to abort(). Any objections to this? Is there a special reason for the 
> current convoluted logic?

For Darwin, I think we want assertion failures to generate crash logs for 
post-mortem analysis.  I’m not sure if SIGABRT will give us the crash logs we 
want.

The choice of a SIGSEGV on 0xbadbeef (for debug builds) and WTFBreakpointTrap() 
e.g. int3 on x86_64 (for release builds), is so that we can discern the crash 
log for an assertion failure vs any other crash.

The reason for release builds using WTFBreakpointTrap() is so that we can get a 
crash with minimal perturbation to the register state, to help with post-mortem 
crash analysis.  Debug builds are only used during development and internal 
testing.  So, we take the opportunity to get more crash info there (hence, the 
dumping of the crash trace).  The reason that ASan builds use __builtin_trap() 
is because ASan does not like the memory access of 0xbadbbeef (if I remember 
correctly).

In addition, we also have infrastructure in place that looks for these crash 
patterns.  So, changing to use SIGABRT (even if it generates a crash log on 
Darwin) would mean additional cost and churn to update that infrastructure, 
with not much gain to show for it.  Hence, I object to the change.

Feel free to change the linux implementation of CRASH() to use abort() if that 
works better for linux folks.  BTW, CRASH() is what you want to 
define/redirect.  WTFCrash() is only one implementation of CRASH().  No client 
should be calling WTFCrash() directly.

Mark

> Michael
> 
> [1] https://bugs.webkit.org/show_bug.cgi?id=153996
> [2] https://bugs.webkit.org/show_bug.cgi?id=183369
> 
> ___
> webkit-dev mailing list
> webkit-dev@lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/webkit-dev

___
webkit-dev mailing list
webkit-dev@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-dev