17 changes: 17 additions & 0 deletions libcxx/lib/abi/x86_64-unknown-linux-gnu.abilist
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__121__basic_string_commonILb1EE20__throw_out_of_rangeEv'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__123__match_any_but_newlineIcE6__execERNS_7__stateIcEE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__123__match_any_but_newlineIwE6__execERNS_7__stateIwEE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__124__libcpp_debug_exception4whatEv'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__15ctypeIcE10do_tolowerEPcPKc'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__15ctypeIcE10do_tolowerEc'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNKSt3__15ctypeIcE10do_toupperEPcPKc'}
Expand Down Expand Up @@ -1136,6 +1137,16 @@
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__121recursive_timed_mutexD1Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__121recursive_timed_mutexD2Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__121undeclare_no_pointersEPcm'}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZNSt3__123__libcpp_debug_functionE', 'size': 8}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC1ERKNS_19__libcpp_debug_infoE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC1ERKS0_'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC1Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC2ERKNS_19__libcpp_debug_infoE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC2ERKS0_'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionC2Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionD0Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionD1Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__124__libcpp_debug_exceptionD2Ev'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__125__num_get_signed_integralIlEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__125__num_get_signed_integralIxEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE'}
Expand All @@ -1154,10 +1165,13 @@
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIwwEEPwEEbT0_S5_T_'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIxxEEPxEEbT0_S5_T_'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__insertion_sort_incompleteIRNS_6__lessIyyEEPyEEbT0_S5_T_'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__libcpp_set_debug_functionEPFvRKNS_19__libcpp_debug_infoEE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__num_get_unsigned_integralIjEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__num_get_unsigned_integralImEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__num_get_unsigned_integralItEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__127__num_get_unsigned_integralIyEET_PKcS3_Rji'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__129__libcpp_abort_debug_functionERKNS_19__libcpp_debug_infoE'}
{'is_defined': True, 'type': 'FUNC', 'name': '_ZNSt3__129__libcpp_throw_debug_functionERKNS_19__libcpp_debug_infoE'}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZNSt3__13cinE', 'size': 168}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZNSt3__14cerrE', 'size': 160}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZNSt3__14clogE', 'size': 160}
Expand Down Expand Up @@ -1554,6 +1568,7 @@
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__120__codecvt_utf8_utf16IwEE', 'size': 24}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__120__time_get_c_storageIcEE', 'size': 16}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__120__time_get_c_storageIwEE', 'size': 16}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__124__libcpp_debug_exceptionE', 'size': 24}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__15ctypeIcEE', 'size': 56}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__15ctypeIwEE', 'size': 56}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTINSt3__16locale5facetE', 'size': 24}
Expand Down Expand Up @@ -1679,6 +1694,7 @@
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__120__codecvt_utf8_utf16IwEE', 'size': 34}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__120__time_get_c_storageIcEE', 'size': 34}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__120__time_get_c_storageIwEE', 'size': 34}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__124__libcpp_debug_exceptionE', 'size': 35}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__15ctypeIcEE', 'size': 18}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__15ctypeIwEE', 'size': 18}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTSNSt3__16locale5facetE', 'size': 22}
Expand Down Expand Up @@ -1790,6 +1806,7 @@
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDiEE', 'size': 96}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IDsEE', 'size': 96}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__120__codecvt_utf8_utf16IwEE', 'size': 96}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__124__libcpp_debug_exceptionE', 'size': 40}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__15ctypeIcEE', 'size': 104}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__15ctypeIwEE', 'size': 136}
{'is_defined': True, 'type': 'OBJECT', 'name': '_ZTVNSt3__16locale5facetE', 'size': 40}
Expand Down
61 changes: 60 additions & 1 deletion libcxx/src/debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,75 @@
//
//===----------------------------------------------------------------------===//

#define _LIBCPP_DEBUG 1
#include "__config"
#include "__debug"
#include "functional"
#include "algorithm"
#include "string"
#include "cstdio"
#include "__hash_table"
#include "mutex"

_LIBCPP_BEGIN_NAMESPACE_STD

static std::string make_what_str(__libcpp_debug_info const& info) {
string msg = info.__file_;
msg += ":" + to_string(info.__line_) + ": _LIBCPP_ASSERT '";
msg += info.__pred_;
msg += "' failed. ";
msg += info.__msg_;
return msg;
}

_LIBCPP_SAFE_STATIC __libcpp_debug_function_type
__libcpp_debug_function = __libcpp_abort_debug_function;

bool __libcpp_set_debug_function(__libcpp_debug_function_type __func) {
__libcpp_debug_function = __func;
return true;
}

_LIBCPP_NORETURN void __libcpp_abort_debug_function(__libcpp_debug_info const& info) {
std::fprintf(stderr, "%s\n", make_what_str(info).c_str());
std::abort();
}

_LIBCPP_NORETURN void __libcpp_throw_debug_function(__libcpp_debug_info const& info) {
throw __libcpp_debug_exception(info);
}

struct __libcpp_debug_exception::__libcpp_debug_exception_imp {
__libcpp_debug_info __info_;
std::string __what_str_;
};

__libcpp_debug_exception::__libcpp_debug_exception() _NOEXCEPT
: __imp_(nullptr) {
}

__libcpp_debug_exception::__libcpp_debug_exception(
__libcpp_debug_info const& info) : __imp_(new __libcpp_debug_exception_imp)
{
__imp_->__info_ = info;
__imp_->__what_str_ = make_what_str(info);
}
__libcpp_debug_exception::__libcpp_debug_exception(
__libcpp_debug_exception const& other) : __imp_(nullptr) {
if (other.__imp_)
__imp_ = new __libcpp_debug_exception_imp(*other.__imp_);
}

__libcpp_debug_exception::~__libcpp_debug_exception() _NOEXCEPT {
if (__imp_)
delete __imp_;
}

const char* __libcpp_debug_exception::what() const _NOEXCEPT {
if (__imp_)
return __imp_->__what_str_.c_str();
return "__libcpp_debug_exception";
}

_LIBCPP_FUNC_VIS
__libcpp_db*
__get_db()
Expand Down
30 changes: 30 additions & 0 deletions libcxx/test/libcxx/debug/debug_abort.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// Test that the default debug handler aborts the program.

#define _LIBCPP_DEBUG 0

#include <csignal>
#include <cstdlib>
#include <__debug>

void signal_handler(int signal)
{
if (signal == SIGABRT)
std::_Exit(EXIT_SUCCESS);
std::_Exit(EXIT_FAILURE);
}

int main()
{
if (std::signal(SIGABRT, signal_handler) != SIG_ERR)
_LIBCPP_ASSERT(false, "foo");
return EXIT_FAILURE;
}
36 changes: 36 additions & 0 deletions libcxx/test/libcxx/debug/debug_throw.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-no-exceptions

// Test that the default debug handler can be overridden and test the
// throwing debug handler.

#define _LIBCPP_DEBUG 0

#include <cstdlib>
#include <exception>
#include <type_traits>
#include <__debug>

int main()
{
{
std::__libcpp_debug_function = std::__libcpp_throw_debug_function;
try {
_LIBCPP_ASSERT(false, "foo");
} catch (std::__libcpp_debug_exception const&) {}
}
{
// test that the libc++ exception type derives from std::exception
static_assert(std::is_base_of<std::exception,
std::__libcpp_debug_exception
>::value, "must be an exception");
}
}
30 changes: 30 additions & 0 deletions libcxx/test/libcxx/debug/debug_throw_register.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: libcpp-no-exceptions

// Test that defining _LIBCPP_DEBUG_USE_EXCEPTIONS causes _LIBCPP_ASSERT
// to throw on failure.

#define _LIBCPP_DEBUG 1
#define _LIBCPP_DEBUG_USE_EXCEPTIONS

#include <cstdlib>
#include <exception>
#include <type_traits>
#include <__debug>
#include <cassert>

int main()
{
try {
_LIBCPP_ASSERT(false, "foo");
assert(false);
} catch (...) {}
}
162 changes: 0 additions & 162 deletions libcxx/www/debug_mode.html

This file was deleted.

1 change: 0 additions & 1 deletion libcxx/www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ <h2>Design Documents</h2>
<li><a href="atomic_design.html"><tt>&lt;atomic&gt;</tt></a></li>
<li><a href="type_traits_design.html"><tt>&lt;type_traits&gt;</tt></a></li>
<li><a href="http://cplusplusmusings.wordpress.com/2012/07/05/clang-and-standard-libraries-on-mac-os-x/">Excellent notes by Marshall Clow</a></li>
<li><a href="debug_mode.html">Status of debug mode</a></li>
</ul>

</div>
Expand Down