options/ansi: implement abort

This commit is contained in:
Kacper Słomiński 2021-06-19 22:21:06 +02:00
parent 3d2c80409c
commit 29f210bd48
3 changed files with 59 additions and 2 deletions

View file

@ -205,9 +205,35 @@ void *calloc(size_t count, size_t size) {
// realloc() is provided by the platform
void abort(void) {
__ensure(!"Not implemented");
__builtin_unreachable();
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGABRT);
if (mlibc::sys_sigprocmask) {
mlibc::sys_sigprocmask(SIG_UNBLOCK, &set, nullptr);
}
raise(SIGABRT);
sigfillset(&set);
sigdelset(&set, SIGABRT);
if (mlibc::sys_sigprocmask) {
mlibc::sys_sigprocmask(SIG_SETMASK, &set, nullptr);
}
struct sigaction sa;
sa.sa_handler = SIG_DFL;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
if (mlibc::sys_sigaction(SIGABRT, &sa, nullptr))
mlibc::panicLogger() << "mlibc: sigaction failed in abort" << frg::endlog;
if (raise(SIGABRT))
mlibc::panicLogger() << "mlibc: raise failed in abort" << frg::endlog;
__builtin_trap();
}
int atexit(void (*func)(void)) {
// TODO: the function pointer types are not compatible;
// the conversion here is undefined behavior. its fine to do

View file

@ -30,6 +30,10 @@ posix_test_cases = [
'system' # This test should be in the ANSI tests, but it depends on sys/wait.h
]
posix_fail_test_cases = [
'abort' # This test should be in the ANSI tests, but it depends on sigaction
]
glibc_test_cases = [
'getopt'
]
@ -65,6 +69,16 @@ if not disable_posix_option
'-no-pie'])
test('posix/' + f, exec)
endforeach
foreach f : posix_fail_test_cases
exec = executable('posix-' + f, ['posix/' + f + '.c', test_sources],
link_with: libc, include_directories: libc_include_dirs,
build_rpath: meson.build_root(),
c_args: '-no-pie',
link_args: ['-Wl,--dynamic-linker=' + meson.build_root() + '/ld.so',
'-no-pie'])
test('posix/' + f, exec, should_fail: true)
endforeach
endif
# We never disable the posix option so glibc is gated behind the posix option here.

17
tests/posix/abort.c Normal file
View file

@ -0,0 +1,17 @@
#include <signal.h>
#include <assert.h>
#include <stdlib.h>
void handler(int sig, siginfo_t *info, void *ctx) { }
int main() {
struct sigaction sa;
sa.sa_sigaction = handler;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
int ret = sigaction(SIGABRT, &sa, NULL);
assert(!ret);
abort();
}