1 : /*
2 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can be
4 : * found in the LICENSE file.
5 : */
6 :
7 : #include <stdlib.h>
8 : #include <stdio.h>
9 :
10 : #include "native_client/src/include/portability.h"
11 : #include "native_client/src/shared/platform/nacl_exit.h"
12 : #include "native_client/src/trusted/service_runtime/nacl_signal.h"
13 :
14 :
15 0 : void NaClAbort(void) {
16 : /*
17 : * We crash the process with a HLT instruction so that the Breakpad
18 : * crash reporter will be invoked when we are running inside Chrome.
19 : *
20 : * This has the disadvantage that an untrusted-code crash will not
21 : * be distinguishable from a trusted-code NaClAbort() based on the
22 : * process's exit status alone
23 : *
24 : * While we could use the INT3 breakpoint instruction to exit (via
25 : * __debugbreak()), that does not work if NaCl's debug exception
26 : * handler is attached, because that always resumes breakpoints (see
27 : * http://code.google.com/p/nativeclient/issues/detail?id=2772).
28 : */
29 0 : while (1) {
30 0 : __halt();
31 0 : }
32 0 : }
33 :
34 0 : void NaClExit(int err_code) {
35 : #ifdef COVERAGE
36 : /* Give coverage runs a chance to flush coverage data */
37 0 : exit(err_code);
38 : #else
39 : /*
40 : * We want to exit without running any finalization code, because
41 : * that could cause currently-running threads to crash.
42 : *
43 : * We avoid using exit() because it calls atexit() handlers. We
44 : * avoid using _exit() because it is documented as doing some
45 : * internal C library shutdown.
46 : *
47 : * We avoid using TerminateProcess() because it terminates threads
48 : * in a non-deterministic order. On Windows, the exit status of a
49 : * process is taken to be the exit status of the last thread that
50 : * exited. Using TerminateProcess() makes the exit status of the
51 : * process unreliable; this used to cause many tests to be flaky.
52 : * See https://code.google.com/p/nativeclient/issues/detail?id=2870
53 : *
54 : * ExitProcess() has the following properties:
55 : *
56 : * - It first terminates all threads except the calling thread.
57 : * This prevents these threads from messing up the process exit
58 : * status.
59 : *
60 : * - It calls loaded DLLs' finalization routines. This is not
61 : * ideal, but it is OK because NaClExit() should only be used for
62 : * graceful exits (when no internal errors have been detected),
63 : * and because there will be no other threads at this point.
64 : */
65 : ExitProcess(err_code);
66 :
67 : /* Just in case. */
68 : NaClAbort();
69 : #endif
70 : }
|