blob: 0bdff7f7d14dfdc4a58241151047219c4a1b3534 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Copyright (C) 1991 Free Software Foundation, Inc.
2This file is part of the GNU C Library.
3
4The GNU C Library is free software; you can redistribute it and/or
5modify it under the terms of the GNU Library General Public License as
6published by the Free Software Foundation; either version 2 of the
7License, or (at your option) any later version.
8
9The GNU C Library is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12Library General Public License for more details.
13
14You should have received a copy of the GNU Library General Public
15License along with the GNU C Library; see the file COPYING.LIB. If
16not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17Cambridge, MA 02139, USA. */
18
19/* Hacked up for uClibc by Erik Andersen */
20
21#include <features.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26#include <signal.h>
27#include <errno.h>
28
29
30
31/* Defeat compiler optimization which assumes function addresses are never NULL */
32static __always_inline int not_null_ptr(const void *p)
33{
34 const void *q;
35 __asm__ (""
36 : "=r" (q) /* output */
37 : "0" (p) /* input */
38 );
39 return q != 0;
40}
41
42/* Our last ditch effort to commit suicide */
43#ifdef __UCLIBC_ABORT_INSTRUCTION__
44# define ABORT_INSTRUCTION __asm__(__UCLIBC_ABORT_INSTRUCTION__)
45#else
46# define ABORT_INSTRUCTION
47# warning "no abort instruction defined for your arch"
48#endif
49
50#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
51extern void weak_function _stdio_term(void) attribute_hidden;
52#endif
53static smallint been_there_done_that = 0;
54
55/* Be prepared in case multiple threads try to abort() */
56#include <bits/uClibc_mutex.h>
57__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
58
59/* Cause an abnormal program termination with core-dump */
60void abort(void)
61{
62 sigset_t sigs;
63 int * p = (int *)(0xffffffff);
64
65 if(*p)
66 printf("zxic abort and assert\n");
67 /* Make sure we acquire the lock before proceeding */
68 __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
69
70 /* Unmask SIGABRT to be sure we can get it */
71 __sigemptyset(&sigs);
72 __sigaddset(&sigs, SIGABRT);
73 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
74
75 while (1) {
76 /* Try to suicide with a SIGABRT */
77 if (been_there_done_that == 0) {
78 been_there_done_that++;
79
80#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
81 /* If we are using stdio, try to shut it down. At the very least,
82 * this will attempt to commit all buffered writes. It may also
83 * unbuffer all writable files, or close them outright.
84 * Check the stdio routines for details. */
85 if (not_null_ptr(_stdio_term)) {
86 _stdio_term();
87 }
88#endif
89
90abort_it:
91 __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock);
92 raise(SIGABRT);
93 __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock);
94 }
95
96 /* Still here? Try to remove any signal handlers */
97 if (been_there_done_that == 1) {
98 struct sigaction act;
99
100 been_there_done_that++;
101 memset(&act, '\0', sizeof(struct sigaction));
102 if (SIG_DFL) /* if it's constant zero, already done */
103 act.sa_handler = SIG_DFL;
104 __sigfillset(&act.sa_mask);
105 sigaction(SIGABRT, &act, NULL);
106
107 goto abort_it;
108 }
109
110 /* Still here? Try to suicide with an illegal instruction */
111 if (been_there_done_that == 2) {
112 been_there_done_that++;
113 ABORT_INSTRUCTION;
114 }
115
116 /* Still here? Try to at least exit */
117 if (been_there_done_that == 3) {
118 been_there_done_that++;
119 _exit(127);
120 }
121
122 /* Still here? We're screwed. Sleepy time. Good night. */
123 while (1)
124 /* Try for ever and ever */
125 ABORT_INSTRUCTION;
126 }
127}
128libc_hidden_def(abort)