This is an automated email from the ASF dual-hosted git repository.

serverglen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brpc.git


The following commit(s) were added to refs/heads/master by this push:
     new 491591cb Support release assert (#2306)
491591cb is described below

commit 491591cb15d8ad40a3e946df51ce36cdfe643036
Author: Bright Chen <[email protected]>
AuthorDate: Fri Jul 14 19:59:49 2023 +0800

    Support release assert (#2306)
    
    * Support release assert
    
    * Support release assert
---
 src/brpc/controller.cpp                     | 33 +++++++++++------------------
 src/brpc/details/naming_service_thread.cpp  |  4 ++--
 src/brpc/http_method.cpp                    | 13 +++++-------
 src/brpc/policy/dynpart_load_balancer.cpp   | 10 +++------
 src/bthread/countdown_event.cpp             |  7 +++---
 src/butil/containers/doubly_buffered_data.h |  8 +++----
 src/butil/logging.h                         |  6 +++---
 src/butil/macros.h                          | 30 ++++++++++++++++++++++++++
 src/butil/memory/scoped_ptr.h               |  3 +--
 src/butil/scoped_generic.h                  |  5 +++--
 src/bvar/detail/agent_group.h               |  4 +---
 src/bvar/mvariable.cpp                      |  7 +++---
 src/bvar/variable.cpp                       | 14 ++++--------
 test/brpc_channel_unittest.cpp              |  6 ++----
 14 files changed, 75 insertions(+), 75 deletions(-)

diff --git a/src/brpc/controller.cpp b/src/brpc/controller.cpp
index c9935a54..338ad66c 100644
--- a/src/brpc/controller.cpp
+++ b/src/brpc/controller.cpp
@@ -1508,26 +1508,20 @@ static void RegisterQuitSignalOrDie() {
     SignalHandler prev = signal(SIGINT, quit_handler);
     if (prev != SIG_DFL &&
         prev != SIG_IGN) { // shell may install SIGINT of background jobs with 
SIG_IGN
-        if (prev == SIG_ERR) {
-            LOG(ERROR) << "Fail to register SIGINT, abort";
-            abort();
-        } else {
-            s_prev_sigint_handler = prev;
-            LOG(WARNING) << "SIGINT was installed with " << prev;
-        }
+        RELEASE_ASSERT_VERBOSE(prev != SIG_ERR,
+                               "Fail to register SIGINT, abort");
+        s_prev_sigint_handler = prev;
+        LOG(WARNING) << "SIGINT was installed with " << prev;
     }
 
     if (FLAGS_graceful_quit_on_sigterm) {
         prev = signal(SIGTERM, quit_handler);
         if (prev != SIG_DFL &&
             prev != SIG_IGN) { // shell may install SIGTERM of background jobs 
with SIG_IGN
-            if (prev == SIG_ERR) {
-                LOG(ERROR) << "Fail to register SIGTERM, abort";
-                abort();
-            } else {
-                s_prev_sigterm_handler = prev;
-                LOG(WARNING) << "SIGTERM was installed with " << prev;
-            }
+            RELEASE_ASSERT_VERBOSE(prev != SIG_ERR,
+                                   "Fail to register SIGTERM, abort");
+            s_prev_sigterm_handler = prev;
+            LOG(WARNING) << "SIGTERM was installed with " << prev;
         }
     }
 
@@ -1535,13 +1529,10 @@ static void RegisterQuitSignalOrDie() {
         prev = signal(SIGHUP, quit_handler);
         if (prev != SIG_DFL &&
             prev != SIG_IGN) { // shell may install SIGHUP of background jobs 
with SIG_IGN
-            if (prev == SIG_ERR) {
-                LOG(ERROR) << "Fail to register SIGHUP, abort";
-                abort();
-            } else {
-                s_prev_sighup_handler = prev;
-                LOG(WARNING) << "SIGHUP was installed with " << prev;
-            }
+            RELEASE_ASSERT_VERBOSE(prev != SIG_ERR,
+                                   "Fail to register SIGHUP, abort");
+            s_prev_sighup_handler = prev;
+            LOG(WARNING) << "SIGHUP was installed with " << prev;
         }
     }
 }
diff --git a/src/brpc/details/naming_service_thread.cpp 
b/src/brpc/details/naming_service_thread.cpp
index 359ef38d..89648e77 100644
--- a/src/brpc/details/naming_service_thread.cpp
+++ b/src/brpc/details/naming_service_thread.cpp
@@ -80,13 +80,13 @@ NamingServiceThread::Actions::~Actions() {
 void NamingServiceThread::Actions::AddServers(
     const std::vector<ServerNode>&) {
     // FIXME(gejun)
-    abort();
+    RELEASE_ASSERT_VERBOSE(false, "Not implemented");
 }
 
 void NamingServiceThread::Actions::RemoveServers(
     const std::vector<ServerNode>&) {
     // FIXME(gejun)
-    abort();
+    RELEASE_ASSERT_VERBOSE(false, "Not implemented");
 }
 
 void NamingServiceThread::Actions::ResetServers(
diff --git a/src/brpc/http_method.cpp b/src/brpc/http_method.cpp
index acb0de1c..b4f5fc43 100644
--- a/src/brpc/http_method.cpp
+++ b/src/brpc/http_method.cpp
@@ -16,7 +16,6 @@
 // under the License.
 
 
-#include <stdlib.h>                     // abort()
 #include "butil/macros.h"
 #include "butil/logging.h"
 #include <pthread.h>
@@ -73,9 +72,8 @@ struct LessThanByName {
 static void BuildHttpMethodMaps() {
     for (size_t i = 0; i < ARRAY_SIZE(g_method_pairs); ++i) {
         const int method = (int)g_method_pairs[i].method;
-        if (method < 0 || method > (int)ARRAY_SIZE(g_method2str_map)) {
-            abort();
-        }
+        RELEASE_ASSERT(method >= 0 &&
+                       method <= (int)ARRAY_SIZE(g_method2str_map));
         g_method2str_map[method] = g_method_pairs[i].str;
      }
     std::sort(g_method_pairs, g_method_pairs + ARRAY_SIZE(g_method_pairs),
@@ -83,10 +81,9 @@ static void BuildHttpMethodMaps() {
     char last_fc = '\0';
     for (size_t i = 0; i < ARRAY_SIZE(g_method_pairs); ++i) {
         char fc = g_method_pairs[i].str[0];
-        if (fc < 'A' || fc > 'Z') {
-            LOG(ERROR) << "Invalid method_name=" << g_method_pairs[i].str;
-            abort();
-        }
+        RELEASE_ASSERT_VERBOSE(fc >= 'A' && fc <= 'Z',
+                               "Invalid method_name=%s",
+                               g_method_pairs[i].str);
         if (fc != last_fc) {
             last_fc = fc;
             g_first_char_index[fc - 'A'] = (uint8_t)(i + 1);
diff --git a/src/brpc/policy/dynpart_load_balancer.cpp 
b/src/brpc/policy/dynpart_load_balancer.cpp
index 4785a0f7..579ca7dd 100644
--- a/src/brpc/policy/dynpart_load_balancer.cpp
+++ b/src/brpc/policy/dynpart_load_balancer.cpp
@@ -127,13 +127,9 @@ int DynPartLoadBalancer::SelectServer(const SelectIn& in, 
SelectOut* out) {
                 && Socket::Address(id, &ptrs[nptr].first) == 0) {
                 int w = schan::GetSubChannelWeight(ptrs[nptr].first->user());
                 total_weight += w;
-                if (nptr < 8) {
-                    ptrs[nptr].second = total_weight;
-                    ++nptr;
-                } else {
-                    CHECK(false) << "Not supported yet";
-                    abort();
-                }
+                RELEASE_ASSERT_VERBOSE(nptr < 8, "Not supported yet");
+                ptrs[nptr].second = total_weight;
+                ++nptr;
             }
         }
         if (nptr != 0) {
diff --git a/src/bthread/countdown_event.cpp b/src/bthread/countdown_event.cpp
index f399a3c8..1c2c5952 100644
--- a/src/bthread/countdown_event.cpp
+++ b/src/bthread/countdown_event.cpp
@@ -26,10 +26,9 @@
 namespace bthread {
 
 CountdownEvent::CountdownEvent(int initial_count) {
-    if (initial_count < 0) {
-        LOG(FATAL) << "Invalid initial_count=" << initial_count;
-        abort();
-    }
+    RELEASE_ASSERT_VERBOSE(initial_count >= 0,
+                           "Invalid initial_count=%d",
+                           initial_count);
     _butex = butex_create_checked<int>();
     *_butex = initial_count;
     _wait_was_invoked = false;
diff --git a/src/butil/containers/doubly_buffered_data.h 
b/src/butil/containers/doubly_buffered_data.h
index 024a5ee8..e011d5da 100644
--- a/src/butil/containers/doubly_buffered_data.h
+++ b/src/butil/containers/doubly_buffered_data.h
@@ -331,9 +331,7 @@ private:
     inline static std::deque<WrapperTLSId>& _get_free_ids() {
         if (BAIDU_UNLIKELY(!_s_free_ids)) {
             _s_free_ids = new (std::nothrow) std::deque<WrapperTLSId>();
-            if (!_s_free_ids) {
-                abort();
-            }
+            RELEASE_ASSERT(_s_free_ids);
         }
         return *_s_free_ids;
     }
@@ -510,8 +508,8 @@ template <typename T, typename TLS, bool 
AllowBthreadSuspended>
 DoublyBufferedData<T, TLS, AllowBthreadSuspended>::DoublyBufferedData()
     : _index(0)
     , _wrapper_key(0) {
-    static_assert(!(AllowBthreadSuspended && !IsVoid<TLS>::value),
-                  "Forbidden to allow suspend bthread with non-Void TLS");
+    BAIDU_CASSERT(!(AllowBthreadSuspended && !IsVoid<TLS>::value),
+                  "Forbidden to allow bthread suspended with non-Void TLS");
 
     _wrappers.reserve(64);
     pthread_mutex_init(&_modify_mutex, NULL);
diff --git a/src/butil/logging.h b/src/butil/logging.h
index 8138af34..c4f8ef00 100644
--- a/src/butil/logging.h
+++ b/src/butil/logging.h
@@ -489,19 +489,19 @@ void print_vlog_sites(VLogSitePrinter*);
 
 // file/line can be specified at running-time. This is useful for printing
 // logs with known file/line inside a LogSink or LogMessageHandler
-#define GET_LOG_AT_MACRO(_1, _2, _3, _4, NAME, ...) NAME
+#define LOG_AT_SELECTOR(_1, _2, _3, _4, NAME, ...) NAME
 
 #define LOG_AT_STREAM1(severity, file, line)                                 \
     ::logging::LogMessage(file, line, ::logging::BLOG_##severity).stream()
 #define LOG_AT_STREAM2(severity, file, line, func)                           \
     ::logging::LogMessage(file, line, func, 
::logging::BLOG_##severity).stream()
-#define LOG_AT_STREAM(...) GET_LOG_AT_MACRO(__VA_ARGS__, LOG_AT_STREAM2, 
LOG_AT_STREAM1)(__VA_ARGS__)
+#define LOG_AT_STREAM(...) LOG_AT_SELECTOR(__VA_ARGS__, LOG_AT_STREAM2, 
LOG_AT_STREAM1)(__VA_ARGS__)
 
 #define LOG_AT1(severity, file, line)                                        \
     BAIDU_LAZY_STREAM(LOG_AT_STREAM(severity, file, line), LOG_IS_ON(severity))
 #define LOG_AT2(severity, file, line, func)                                   \
     BAIDU_LAZY_STREAM(LOG_AT_STREAM(severity, file, line, func), 
LOG_IS_ON(severity))
-#define LOG_AT(...) GET_LOG_AT_MACRO(__VA_ARGS__, LOG_AT2, 
LOG_AT1)(__VA_ARGS__)
+#define LOG_AT(...) LOG_AT_SELECTOR(__VA_ARGS__, LOG_AT2, LOG_AT1)(__VA_ARGS__)
 
 
 // The VLOG macros log with negative verbosities.
diff --git a/src/butil/macros.h b/src/butil/macros.h
index 6b7f4468..6519a105 100644
--- a/src/butil/macros.h
+++ b/src/butil/macros.h
@@ -12,8 +12,10 @@
 
 #include <stddef.h>  // For size_t.
 #include <string.h>  // For memcpy.
+#include <stdlib.h>
 
 #include "butil/compiler_specific.h"  // For ALLOW_UNUSED.
+#include "butil/string_printf.h"      // For butil::string_printf().
 
 // There must be many copy-paste versions of these macros which are same
 // things, undefine them to avoid conflict.
@@ -442,4 +444,32 @@ namespace {  /*anonymous namespace */                      
     \
 
 #endif  // __cplusplus
 
+#define ASSERT_LOG(fmt, ...)                                            \
+    do {                                                                \
+        std::string log = butil::string_printf(fmt, ## __VA_ARGS__);    \
+        LOG(FATAL) << log;                                              \
+    } while (false)
+
+// Assert macro that can crash the process to generate a dump.
+#define RELEASE_ASSERT(condition)   \
+    do {                            \
+        if (!(condition)) {         \
+            ::abort();              \
+        }                           \
+    } while (false)
+
+// Assert macro that can crash the process to generate a dump and
+// supply a verbose explanation of what went wrong.
+// For example:
+//  std::vector<int> v;
+//  ...
+//  RELEASE_ASSERT_VERBOSE(v.empty(), "v should be empty, but with size=%zu", 
v.size());
+#define RELEASE_ASSERT_VERBOSE(condition, fmt, ...)                            
     \
+    do {                                                                       
     \
+        if (!(condition)) {                                                    
     \
+            ASSERT_LOG("Assert failure: " #condition ". " #fmt, ## 
__VA_ARGS__);    \
+            ::abort();                                                         
     \
+        }                                                                      
     \
+    } while (false)
+
 #endif  // BUTIL_MACROS_H_
diff --git a/src/butil/memory/scoped_ptr.h b/src/butil/memory/scoped_ptr.h
index 61a44df4..0f435cd6 100644
--- a/src/butil/memory/scoped_ptr.h
+++ b/src/butil/memory/scoped_ptr.h
@@ -223,8 +223,7 @@ class scoped_ptr_impl {
 
   void reset(T* p) {
     // This is a self-reset, which is no longer allowed: 
http://crbug.com/162971
-    if (p != NULL && p == data_.ptr)
-      abort();
+    RELEASE_ASSERT(p == NULL || p != data_.ptr);
 
     // Note that running data_.ptr = p can lead to undefined behavior if
     // get_deleter()(get()) deletes this. In order to prevent this, reset()
diff --git a/src/butil/scoped_generic.h b/src/butil/scoped_generic.h
index 8310c713..d6d71971 100644
--- a/src/butil/scoped_generic.h
+++ b/src/butil/scoped_generic.h
@@ -11,6 +11,7 @@
 
 #include "butil/compiler_specific.h"
 #include "butil/move.h"
+#include "butil/macros.h"
 
 namespace butil {
 
@@ -96,8 +97,8 @@ class ScopedGeneric {
   // object, if given. Self-resets are not allowd as on scoped_ptr. See
   // http://crbug.com/162971
   void reset(const element_type& value = traits_type::InvalidValue()) {
-    if (data_.generic != traits_type::InvalidValue() && data_.generic == value)
-      abort();
+    RELEASE_ASSERT(data_.generic == traits_type::InvalidValue() ||
+                   data_.generic != value);
     FreeIfNecessary();
     data_.generic = value;
   }
diff --git a/src/bvar/detail/agent_group.h b/src/bvar/detail/agent_group.h
index ceb7c05d..db327f27 100644
--- a/src/bvar/detail/agent_group.h
+++ b/src/bvar/detail/agent_group.h
@@ -172,9 +172,7 @@ private:
     inline static std::deque<AgentId> &_get_free_ids() {
         if (__builtin_expect(!_s_free_ids, 0)) {
             _s_free_ids = new (std::nothrow) std::deque<AgentId>();
-            if (!_s_free_ids) {
-                abort();
-            }
+            RELEASE_ASSERT(_s_free_ids);
         }
         return *_s_free_ids;
     }
diff --git a/src/bvar/mvariable.cpp b/src/bvar/mvariable.cpp
index 29caddff..bff17183 100644
--- a/src/bvar/mvariable.cpp
+++ b/src/bvar/mvariable.cpp
@@ -167,10 +167,9 @@ int MVariable::expose_impl(const butil::StringPiece& 
prefix,
         }
     }
 
-    if (FLAGS_bvar_abort_on_same_name) {
-        LOG(FATAL) << "Abort due to name conflict";
-        abort();
-    } else if (!s_bvar_may_abort) {
+    RELEASE_ASSERT_VERBOSE(!FLAGS_bvar_abort_on_same_name,
+                           "Abort due to name conflict");
+    if (!s_bvar_may_abort) {
         // Mark name conflict occurs, If this conflict happens before
         // initialization of bvar_abort_on_same_name, the validator will
         // abort the program if needed.
diff --git a/src/bvar/variable.cpp b/src/bvar/variable.cpp
index 9e623179..bd6de08a 100644
--- a/src/bvar/variable.cpp
+++ b/src/bvar/variable.cpp
@@ -48,12 +48,7 @@ DEFINE_bool(bvar_abort_on_same_name, false,
 // Remember abort request before bvar_abort_on_same_name is initialized.
 bool s_bvar_may_abort = false;
 static bool validate_bvar_abort_on_same_name(const char*, bool v) {
-    if (v && s_bvar_may_abort) {
-        // Name conflict happens before handling args of main(), this is
-        // generally caused by global bvar.
-        LOG(FATAL) << "Abort due to name conflict";
-        abort();
-    }
+    RELEASE_ASSERT_VERBOSE(!v || !s_bvar_may_abort, "Abort due to name 
conflict");
     return true;
 }
 const bool ALLOW_UNUSED dummy_bvar_abort_on_same_name = 
::GFLAGS_NS::RegisterFlagValidator(
@@ -167,10 +162,9 @@ int Variable::expose_impl(const butil::StringPiece& prefix,
             return 0;
         }
     }
-    if (FLAGS_bvar_abort_on_same_name) {
-        LOG(FATAL) << "Abort due to name conflict";
-        abort();
-    } else if (!s_bvar_may_abort) {
+    RELEASE_ASSERT_VERBOSE(!FLAGS_bvar_abort_on_same_name,
+                           "Abort due to name conflict");
+    if (!s_bvar_may_abort) {
         // Mark name conflict occurs, If this conflict happens before
         // initialization of bvar_abort_on_same_name, the validator will
         // abort the program if needed.
diff --git a/test/brpc_channel_unittest.cpp b/test/brpc_channel_unittest.cpp
index f5806ccd..6d7d374b 100644
--- a/test/brpc_channel_unittest.cpp
+++ b/test/brpc_channel_unittest.cpp
@@ -76,10 +76,8 @@ public:
     DeleteOnlyOnceChannel() : _c(1) {
     }
     ~DeleteOnlyOnceChannel() {
-        if (_c.fetch_sub(1) != 1) {
-            LOG(ERROR) << "Delete more than once!";
-            abort();
-        }
+        RELEASE_ASSERT_VERBOSE(_c.fetch_sub(1) == 1,
+                               "Delete more than once!");
     }
 private:
     butil::atomic<int> _c;


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to