mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-15 18:19:00 +01:00
cxx: Add KConfig option for C++ exceptions, disable by default
Fixes https://github.com/espressif/esp-idf/issues/1072 (Additional 20KB is still used if C++ exception support is enabled in menuconfig.)
This commit is contained in:
committed by
Angus Gratton
parent
6f07e0797d
commit
9c7477ef34
@@ -1,3 +1,11 @@
|
||||
# Mark __cxa_guard_dummy as undefined so that implementation of static guards
|
||||
# is taken from cxx_guards.o instead of libstdc++.a
|
||||
COMPONENT_ADD_LDFLAGS += -u __cxa_guard_dummy
|
||||
|
||||
ifndef CONFIG_CXX_EXCEPTIONS
|
||||
# If exceptions are disabled, ensure our fatal exception
|
||||
# hooks are preferentially linked over libstdc++ which
|
||||
# has full exception support
|
||||
COMPONENT_ADD_LDFLAGS += -u __cxx_fatal_exception
|
||||
endif
|
||||
|
||||
|
||||
87
components/cxx/cxx_exception_stubs.cpp
Normal file
87
components/cxx/cxx_exception_stubs.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <exception>
|
||||
#include <bits/functexcept.h>
|
||||
#include <sdkconfig.h>
|
||||
|
||||
#ifndef CONFIG_CXX_EXCEPTIONS
|
||||
|
||||
const char *FATAL_EXCEPTION = "Fatal C++ exception: ";
|
||||
|
||||
extern "C" void __cxx_fatal_exception(void)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
extern "C" void __cxx_fatal_exception_message(const char *msg)
|
||||
{
|
||||
printf("%s%s\n", FATAL_EXCEPTION, msg);
|
||||
abort();
|
||||
}
|
||||
|
||||
extern "C" void __cxx_fatal_exception_int(int i)
|
||||
{
|
||||
printf("%s (%d)\n", FATAL_EXCEPTION, i);
|
||||
abort();
|
||||
}
|
||||
|
||||
void std::__throw_bad_exception(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
void std::__throw_bad_alloc(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
void std::__throw_bad_cast(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
void std::__throw_bad_typeid(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
void std::__throw_logic_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_domain_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_invalid_argument(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_length_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_out_of_range(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_out_of_range_fmt(const char*, ...) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_runtime_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_range_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_overflow_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_underflow_error(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_ios_failure(const char*) __attribute__((alias("__cxx_fatal_exception_message")));
|
||||
|
||||
void std::__throw_system_error(int) __attribute__((alias("__cxx_fatal_exception_int")));
|
||||
|
||||
void std::__throw_bad_function_call(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
void std::__throw_future_error(int) __attribute__((alias("__cxx_fatal_exception_int")));
|
||||
|
||||
|
||||
/* The following definitions are needed because libstdc++ is also compiled with
|
||||
__throw_exception_again defined to throw, and some other exception code in a few places.
|
||||
|
||||
This cause exception handler code to be emitted in the library even though it's mostly
|
||||
unreachable (as any libstdc++ "throw" will first call one of the above stubs, which will abort).
|
||||
|
||||
If these are left out, a bunch of unwanted exception handler code is linked.
|
||||
|
||||
Note: these function prototypes are not correct.
|
||||
*/
|
||||
|
||||
extern "C" void __cxa_allocate_exception(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_begin_catch(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_end_catch(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_get_exception_ptr(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_free_exception(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_rethrow(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_throw(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
extern "C" void __cxa_call_terminate(void) __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
bool std::uncaught_exception() __attribute__((alias("__cxx_fatal_exception")));
|
||||
|
||||
#endif // CONFIG_CXX_EXCEPTIONS
|
||||
@@ -188,8 +188,12 @@ TEST_CASE("before scheduler has started, static initializers work correctly", "[
|
||||
TEST_ASSERT_EQUAL(2, StaticInitTestBeforeScheduler::order);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CXX_EXCEPTIONS
|
||||
|
||||
TEST_CASE("c++ exceptions work", "[cxx]")
|
||||
{
|
||||
/* Note: This test currently trips the memory leak threshold
|
||||
as libunwind allocates ~4KB of data on first exception. */
|
||||
int thrown_value;
|
||||
try
|
||||
{
|
||||
@@ -203,6 +207,8 @@ TEST_CASE("c++ exceptions work", "[cxx]")
|
||||
printf("OK?\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* These test cases pull a lot of code from libstdc++ and are disabled for now
|
||||
*/
|
||||
#if 0
|
||||
|
||||
Reference in New Issue
Block a user