Skip to content

[libc++][hardening] Add an experimental function to log hardening errors #149452

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,7 @@ set(files
__locale_dir/time.h
__locale_dir/wbuffer_convert.h
__locale_dir/wstring_convert.h
__log_hardening_failure
__math/abs.h
__math/copysign.h
__math/error_functions.h
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _LIBCPP_HAS_EXPERIMENTAL_PSTL _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# define _LIBCPP_HAS_EXPERIMENTAL_TZDB _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# define _LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM _LIBCPP_HAS_EXPERIMENTAL_LIBRARY
# define _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC _LIBCPP_HAS_EXPERIMENTAL_LIBRARY

# if defined(__MVS__)
# include <features.h> // for __NATIVE_ASCII_F
Expand Down
42 changes: 42 additions & 0 deletions libcxx/include/__log_hardening_failure
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___LOG_HARDENING_FAILURE
#define _LIBCPP___LOG_HARDENING_FAILURE

#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

// Hardening logging is not available in the C++03 mode; moreover, it is currently only available in the experimental
// library.
#if _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG)

_LIBCPP_BEGIN_NAMESPACE_STD

// This function should never be called directly from the code -- it should only be called through the
// `_LIBCPP_LOG_HARDENING_FAILURE` macro.
[[__gnu__::__cold__]] _LIBCPP_EXPORTED_FROM_ABI void __log_hardening_failure(const char* __message) noexcept;

// _LIBCPP_LOG_HARDENING_FAILURE(message)
//
// This macro is used to log an error without terminating the program (as is the case for hardening failures if the
// `observe` assertion semantic is used).

# if !defined(_LIBCPP_LOG_HARDENING_FAILURE)
# define _LIBCPP_LOG_HARDENING_FAILURE(__message) ::std::__log_hardening_failure(__message)
# endif // !defined(_LIBCPP_LOG_HARDENING_FAILURE)

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC && !defined(_LIBCPP_CXX03_LANG)

#endif // _LIBCPP___LOG_HARDENING_FAILURE
3 changes: 3 additions & 0 deletions libcxx/include/module.modulemap.in
Original file line number Diff line number Diff line change
Expand Up @@ -2353,6 +2353,9 @@ module std [system] {
header "__std_mbstate_t.h"
export *
}
module log_hardening_failure {
header "__log_hardening_failure"
}
module verbose_abort {
header "__verbose_abort"
}
Expand Down
1 change: 1 addition & 0 deletions libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ add_custom_target(cxx DEPENDS ${LIBCXX_BUILD_TARGETS})
# Build the experimental static library
set(LIBCXX_EXPERIMENTAL_SOURCES
experimental/keep.cpp
experimental/log_hardening_failure.cpp
)

if (LIBCXX_PSTL_BACKEND STREQUAL "libdispatch")
Expand Down
31 changes: 31 additions & 0 deletions libcxx/src/experimental/log_hardening_failure.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <__config>
#include <__log_hardening_failure>
#include <cstdio>

#ifdef __BIONIC__
# include <syslog.h>
#endif // __BIONIC__

_LIBCPP_BEGIN_NAMESPACE_STD

void __log_hardening_failure(const char* message) noexcept {
// Always log the message to `stderr` in case the platform-specific system calls fail.
std::fputs(message, stderr);

#if defined(__BIONIC__)
// Show error in logcat. The latter two arguments are ignored on Android.
openlog("libc++", 0, 0);
syslog(LOG_CRIT, "%s", message);
closelog();
#endif
}

_LIBCPP_END_NAMESPACE_STD
26 changes: 26 additions & 0 deletions libcxx/test/libcxx/assertions/log_hardening_failure.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// Basic smoke test for `__log_hardening_failure`.
//
// UNSUPPORTED: c++03
// UNSUPPORTED: libcpp-has-no-experimental-hardening-observe-semantic

#include <__log_hardening_failure>

#include "test_macros.h"

ASSERT_NOEXCEPT(std::__log_hardening_failure(""));

int main(int, char**) {
std::__log_hardening_failure("Some message");
// It's difficult to properly test platform-specific logging behavior of the function; just make sure it exists and
// can be called at runtime.

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@
#if !_LIBCPP_HAS_EXPERIMENTAL_SYNCSTREAM
# error "-fexperimental-library should enable the syncstream header"
#endif

#if !_LIBCPP_HAS_EXPERIMENTAL_HARDENING_OBSERVE_SEMANTIC
# error "-fexperimental-library should allow using the Hardening observe semantic"
#endif
1 change: 1 addition & 0 deletions libcxx/utils/libcxx/test/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ def getSuitableClangTidy(cfg):
AddFeature("libcpp-has-no-incomplete-pstl"),
AddFeature("libcpp-has-no-experimental-tzdb"),
AddFeature("libcpp-has-no-experimental-syncstream"),
AddFeature("libcpp-has-no-experimental-hardening-observe-semantic"),
],
),
# TODO: This can be improved once we use a version of GoogleBenchmark that supports the dry-run mode.
Expand Down
Loading