Optional Two-phase heap tracing
[hiphop-php.git] / hphp / util / assertions.cpp
blob5ea976dc00424f7e00ac34df89b7217ab6d225c0
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/util/assertions.h"
19 #include <folly/Format.h>
21 #include <cstdio>
22 #include <functional>
23 #include <iostream>
24 #include <string>
25 #include <vector>
27 namespace HPHP {
28 ///////////////////////////////////////////////////////////////////////////////
30 static AssertFailLogger s_logger;
32 __thread AssertDetailImpl* AssertDetailImpl::s_head = nullptr;
34 ///////////////////////////////////////////////////////////////////////////////
36 bool AssertDetailImpl::log_impl(const AssertDetailImpl* adi) {
37 if (!adi) return false;
38 log_impl(adi->m_next);
40 auto const title = folly::format("{:-^80}\n", adi->m_name).str();
41 auto const msg = adi->run();
43 fprintf(stderr, "\n%s%s\n", title.c_str(), msg.c_str());
44 if (s_logger) s_logger(title.c_str(), msg);
46 return true;
49 bool AssertDetailImpl::log() { return log_impl(s_head); }
51 //////////////////////////////////////////////////////////////////////
53 void assert_log_failure(const char* e, const std::string& msg) {
54 fprintf(stderr, "\nAssertion failure: %s\n%s\n", e, msg.c_str());
56 if (s_logger) {
57 s_logger("Assertion Failure", e);
58 if (!msg.empty()) {
59 s_logger("Assertion Message", msg);
62 auto const detailed = AssertDetailImpl::log();
63 fprintf(stderr, "\n");
65 // Reprint the original message, so readers don't necessarily have to page up
66 // through all the detail to find it. We also printed it first, just in case
67 // one of the detailers wanted to segfault.
68 if (detailed) {
69 fprintf(stderr, "\nAssertion failure: %s\n%s\n", e, msg.c_str());
73 void assert_fail(const char* e, const char* file,
74 unsigned int line, const char* func,
75 const std::string& msg) {
76 auto const assertion = folly::format("{}:{}: {}: assertion `{}' failed.",
77 file, line, func, e).str();
78 assert_log_failure(assertion.c_str(), msg);
80 std::abort();
83 void assert_fail_no_log(
84 const char* e,
85 const char* file,
86 unsigned int line,
87 const char* func,
88 const std::string& msg
89 ) {
90 auto const assertion = folly::sformat("{}:{}: {}: assertion `{}' failed.",
91 file, line, func, e);
92 fprintf(stderr, "\nAssertion failure: %s\n%s\n",
93 assertion.c_str(), msg.c_str());
94 std::abort();
97 void register_assert_fail_logger(AssertFailLogger l) {
98 s_logger = l;
101 ///////////////////////////////////////////////////////////////////////////////