tor/src/test/test_bt_cl.c
Nick Mathewson 9bbd6502f0 Use autoconf, not gcc version, to decide which warnings we have
This gives more accurate results under Clang, which can only help us
detect more warnings in more places.

Fixes bug 19216; bugfix on 0.2.0.1-alpha
2016-06-11 10:11:53 -04:00

133 lines
2.9 KiB
C

/* Copyright (c) 2012-2016, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "orconfig.h"
#include <stdio.h>
#include <stdlib.h>
/* To prevent 'assert' from going away. */
#undef TOR_COVERAGE
#include "or.h"
#include "util.h"
#include "backtrace.h"
#include "torlog.h"
/* -1: no crash.
* 0: crash with a segmentation fault.
* 1x: crash with an assertion failure. */
static int crashtype = 0;
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define NORETURN __attribute__((noreturn))
#endif
int crash(int x) NOINLINE;
int oh_what(int x) NOINLINE;
int a_tangled_web(int x) NOINLINE;
int we_weave(int x) NOINLINE;
static void abort_handler(int s) NORETURN;
#ifdef HAVE_CFLAG_WNULL_DEREFERENCE
DISABLE_GCC_WARNING(null-dereference)
#endif
int
crash(int x)
{
if (crashtype == 0) {
#if defined(__clang_analyzer__) || defined(__COVERITY__)
tor_assert(1 == 0); /* Avert your eyes, clangalyzer and coverity! You
* don't need to see us dereference NULL. */
#else
*(volatile int *)0 = 0;
#endif
} else if (crashtype == 1) {
tor_assert(1 == 0);
} else if (crashtype == -1) {
;
}
crashtype *= x;
return crashtype;
}
#ifdef HAVE_CFLAG_WNULL_DEREFERENCE
ENABLE_GCC_WARNING(null-dereference)
#endif
int
oh_what(int x)
{
/* We call crash() twice here, so that the compiler won't try to do a
* tail-call optimization. Only the first call will actually happen, but
* telling the compiler to maybe do the second call will prevent it from
* replacing the first call with a jump. */
return crash(x) + crash(x*2);
}
int
a_tangled_web(int x)
{
return oh_what(x) * 99 + oh_what(x);
}
int
we_weave(int x)
{
return a_tangled_web(x) + a_tangled_web(x+1);
}
static void
abort_handler(int s)
{
(void)s;
exit(0);
}
int
main(int argc, char **argv)
{
log_severity_list_t severity;
if (argc < 2) {
puts("I take an argument. It should be \"assert\" or \"crash\" or "
"\"backtraces\" or \"none\"");
return 1;
}
#if !(defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION))
puts("Backtrace reporting is not supported on this platform");
return 77;
#endif
if (!strcmp(argv[1], "assert")) {
crashtype = 1;
} else if (!strcmp(argv[1], "crash")) {
crashtype = 0;
} else if (!strcmp(argv[1], "none")) {
crashtype = -1;
} else if (!strcmp(argv[1], "backtraces")) {
return 0;
} else {
puts("Argument should be \"assert\" or \"crash\" or \"none\"");
return 1;
}
init_logging(1);
set_log_severity_config(LOG_WARN, LOG_ERR, &severity);
add_stream_log(&severity, "stdout", STDOUT_FILENO);
tor_log_update_sigsafe_err_fds();
configure_backtrace_handler(NULL);
signal(SIGABRT, abort_handler);
printf("%d\n", we_weave(2));
clean_up_backtrace_handler();
logs_free_all();
return 0;
}