util/check: Add CHECK_NONFATAL identity function and NONFATAL_UNREACHABLE macro #24812

pull aureleoules wants to merge 1 commits into bitcoin:master from aureleoules:check_non_fatal_identity changing 7 files +49 −39
  1. aureleoules commented at 11:48 pm on April 8, 2022: member

    This PR replaces the macro CHECK_NONFATAL with an identity function.
    I simplified the usage of CHECK_NONFATAL where applicable in src/rpc.
    This function is useful in sanity checks for RPC and command-line interfaces.

    Context: #24804 (review).

    Also adds UNREACHABLE_NONFATAL macro.

  2. aureleoules force-pushed on Apr 9, 2022
  3. aureleoules force-pushed on Apr 9, 2022
  4. DrahtBot added the label RPC/REST/ZMQ on Apr 9, 2022
  5. DrahtBot added the label Utils/log/libs on Apr 9, 2022
  6. in src/util/check.h:98 in 5eeb1e55e5 outdated
    93+ *
    94+ * - Should be used to run non-fatal checks.
    95+ * - For fatal errors, use Assert().
    96+ * - Appropriate for non-fatal errors in interactive sessions (e.g. RPC or command line interfaces).
    97+ */
    98+#define CheckNonFatal(val) inline_check_non_fatal(val, __FILE__, __LINE__, __func__, #val)
    


    MarcoFalke commented at 6:59 am on April 9, 2022:
    I think you can just recycle the existing name. No need to add a second one.

    aureleoules commented at 9:28 am on April 10, 2022:
    It’s now replaced I had to add unreachable return statements like below otherwise the CI would complain https://github.com/bitcoin/bitcoin/blob/0661baffe8044cc049f6494ab29b79f5e4b00998/src/rpc/util.cpp#L986-L993
  7. aureleoules force-pushed on Apr 9, 2022
  8. aureleoules force-pushed on Apr 9, 2022
  9. aureleoules force-pushed on Apr 10, 2022
  10. aureleoules renamed this:
    util/check: Add CheckNonFatal identity function and use it in src/rpc
    util/check: Replace CHECK_NONFATAL macro with identity function and use it in src/rpc
    on Apr 10, 2022
  11. fanquake deleted a comment on Apr 10, 2022
  12. DrahtBot commented at 1:50 am on April 11, 2022: member

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #24455 (refactor: Split ArgsManager out of util/system by Empact)
    • #22341 (rpc: add getxpub by Sjors)
    • #19792 (rpc: Add dumpcoinstats by fjahr)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  13. in src/wallet/rpc/backup.cpp:919 in 0661baffe8 outdated
    915@@ -916,6 +916,7 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
    916         return "unrecognized script";
    917     } // no default case, so the compiler can warn about missing cases
    918     CHECK_NONFATAL(false);
    919+    return ""; // not reached
    


    MarcoFalke commented at 9:35 am on April 11, 2022:

    Hmm, I am wondering if it makes sense to introduce a macro that throws NonFatalCheckError unconditionally?

    CHECK_NONFATAL(false) is inspired by assert(false) to mark unreachable code. Though, hiding the implementation behind a function call makes it harder for the compiler to realize the function never returns when called with false. (The same happens when using Assert(false)).


    aureleoules commented at 7:36 pm on April 11, 2022:
    How about a macro UNREACHABLE_NONFATAL() and UNREACHABLE()?

    vincenzopalazzo commented at 11:37 pm on April 11, 2022:

    Hmm, I am wondering if it makes sense to introduce a macro that throws NonFatalCheckError unconditionally?

    CHECK_NONFATAL(false) is inspired by assert(false) to mark unreachable code. Though, hiding the implementation behind a function call makes it harder for the compiler to realize the function never returns when called with false. (The same happens when using Assert(false)).

    Concept ACK, this will make the code much cleaner

  14. aureleoules force-pushed on Apr 12, 2022
  15. in src/util/check.h:98 in 36654224a6 outdated
    93+#define NONFATAL_UNREACHABLE()                                                       \
    94+    do {                                                                             \
    95+        throw NonFatalCheckError(                                                    \
    96+            format_internal_error("Unreachable code reached",                        \
    97+                                  __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT)); \
    98+    } while (0)
    


    vincenzopalazzo commented at 6:10 am on April 12, 2022:
    0    } while (false)
    

    MarcoFalke commented at 6:18 am on April 12, 2022:
    do-while-0 is only used when there is a need to force a trailing semicolon or to bundle several statements or “leaking” statements into one, none of which apply here, so it could be dropped as well?

    vincenzopalazzo commented at 6:23 am on April 12, 2022:
    Concept ACK

    aureleoules commented at 11:47 am on April 12, 2022:
    Fixed it
  16. vincenzopalazzo changes_requested
  17. vincenzopalazzo commented at 6:11 am on April 12, 2022: none
    LGTM, but I’m not a big fan of while(0) in C++, maybe C in yes
  18. in src/util/check.h:27 in 36654224a6 outdated
    22+    strprintf("Internal bug detected: '%s'\n%s:%d (%s)\nPlease report this issue here: %s\n", \
    23+              msg, file, line, func, report)
    24+
    25+/** Helper for CHECK_NONFATAL() */
    26+template <typename T>
    27+T&& inline_check_non_fatal(T&& val, [[maybe_unused]] const char* file, [[maybe_unused]] int line, [[maybe_unused]] const char* func, [[maybe_unused]] const char* assertion)
    


    MarcoFalke commented at 6:19 am on April 12, 2022:
    Are the maybe_unused used or actually unused here?

    aureleoules commented at 11:47 am on April 12, 2022:
    Removed annotations
  19. in src/util/check.h:107 in 36654224a6 outdated
    102+ * This is used to mark code that is not yet implemented or is not yet reachable.
    103+ */
    104+#define UNREACHABLE()                                                                                                                 \
    105+    do {                                                                                                                              \
    106+        std::cerr << format_internal_error("Unreachable code reached", __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT) << std::endl; \
    107+        abort();                                                                                                                      \
    


    MarcoFalke commented at 6:20 am on April 12, 2022:
    0        std::abort();                                                                                                                      \
    

    aureleoules commented at 11:48 am on April 12, 2022:
    Fixed it
  20. MarcoFalke approved
  21. MarcoFalke commented at 6:20 am on April 12, 2022: member
    lgtm
  22. aureleoules force-pushed on Apr 12, 2022
  23. aureleoules commented at 11:49 am on April 12, 2022: member
    I’ve addressed the nits, thanks for your reviews.
  24. aureleoules renamed this:
    util/check: Replace CHECK_NONFATAL macro with identity function and use it in src/rpc
    util/check: Add CHECK_NONFATAL identity function, NONFATAL_UNREACHABLE AND UNREACHABLE macros
    on Apr 12, 2022
  25. vincenzopalazzo approved
  26. in src/util/check.h:95 in 1e4d38267f outdated
    90+ * NONFATAL_UNREACHABLE() is a macro that is used to mark unreachable code. It throws a NonFatalCheckError.
    91+ * This is used to mark code that is not yet implemented or is not yet reachable.
    92+ */
    93+#define NONFATAL_UNREACHABLE()                            \
    94+    throw NonFatalCheckError(                             \
    95+        format_internal_error("Unreachable code reached", \
    


    jonatack commented at 12:20 pm on April 13, 2022:

    maybe

    0        format_internal_error("Unreachable code reached (non-fatal)", \
    
  27. in src/util/check.h:104 in 1e4d38267f outdated
     99+ * UNREACHABLE is a macro that is used to mark unreachable code. It aborts the program.
    100+ * This is used to mark code that is not yet implemented or is not yet reachable.
    101+ */
    102+#define UNREACHABLE()                                                                                                                 \
    103+    do {                                                                                                                              \
    104+        std::cerr << format_internal_error("Unreachable code reached", __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT) << std::endl; \
    


    jonatack commented at 12:44 pm on April 13, 2022:

    maybe

    0        std::cerr << format_internal_error("Unreachable code reached (fatal, aborting)", __FILE__, __LINE__, __func__, PACKAGE_BUGREPORT) << std::endl; \
    
  28. jonatack commented at 12:45 pm on April 13, 2022: member

    ACK 1e4d38267feb69bab20ed06367d0a0adcd211068

    Tested NONFATAL_UNREACHABLE

    0error code: -1
    1error message:
    2Internal bug detected: 'Unreachable code reached'
    3wallet/rpc/addresses.cpp:38 (operator())
    4Please report this issue here: https://github.com/bitcoin/bitcoin/issues
    

    Tested UNREACHABLE

    0Internal bug detected: 'Unreachable code reached'
    1wallet/rpc/addresses.cpp:38 (operator())
    2Please report this issue here: https://github.com/bitcoin/bitcoin/issues
    3
    4Aborted
    

    If you retouch, it looks like #include <util/check.h> ought to be added to /rpc/blockchain.cpp and /rpc/util.cpp as well here.

  29. in src/util/check.h:22 in 1e4d38267f outdated
    17@@ -18,8 +18,24 @@ class NonFatalCheckError : public std::runtime_error
    18     using std::runtime_error::runtime_error;
    19 };
    20 
    21+#define format_internal_error(msg, file, line, func, report)                                  \
    22+    strprintf("Internal bug detected: '%s'\n%s:%d (%s)\nPlease report this issue here: %s\n", \
    


    jonatack commented at 12:54 pm on April 13, 2022:
    0    strprintf("Internal bug detected: \"%s\"\n%s:%d (%s)\nPlease report this issue here: %s\n", \
    

    which would output the following, for example:

    0error code: -1
    1error message:
    2Internal bug detected: "Unreachable code reached"
    3wallet/rpc/addresses.cpp:38 (operator())
    4Please report this issue here: https://github.com/bitcoin/bitcoin/issues
    
  30. aureleoules force-pushed on Apr 13, 2022
  31. aureleoules force-pushed on Apr 13, 2022
  32. jonatack commented at 2:24 pm on April 13, 2022: member
    re-ACK 63b753416abddb5f82ed32ff64a3372e65722fc2
  33. MarcoFalke commented at 11:59 am on April 15, 2022: member

    Might be good to adjust the rpc linter as well for the new macros: #24856

    Can be done in a follow-up to avoid a conflict for now.

  34. in src/util/check.h:102 in 63b753416a outdated
     97+
     98+/**
     99+ * UNREACHABLE is a macro that is used to mark unreachable code. It aborts the program.
    100+ * This is used to mark code that is not yet implemented or is not yet reachable.
    101+ */
    102+#define UNREACHABLE()                                                                                                                                   \
    


    MarcoFalke commented at 7:22 am on April 16, 2022:
    This is unused and on a second thought I wonder if there is any value in it. The current code can already use assert(false) just fine. Introducing another way to write assert(false) will just lead to bike-shedding without any benefit.

    vincenzopalazzo commented at 7:42 am on April 16, 2022:

    in favor to have a macro like UNREACHABLE is that we can the possibility to add more failures to the error message, that it is always good.

    Maybe somethings assert(false && "err message") can be a good motivation to have this macros, otherwise I agree with @MarcoFalke


    MarcoFalke commented at 7:45 am on April 16, 2022:
    I think that this is unreachable code, so by definition it is not something that a user will (or should) ever see. So there is not much benefit in spending time to overengineer error messages and formatting of them.

    aureleoules commented at 12:44 pm on April 16, 2022:

    I think that this is unreachable code, so by definition it is not something that a user will (or should) ever see.

    It could be useful for developers modifying code and stumbling across an unreachable block as a result. Though I agree that it’s not an essential feature considering assert(false) works alright.


    MarcoFalke commented at 1:01 pm on April 16, 2022:
    Developers would already know what assert(false) means and what it does. Printing PACKAGE_BUGREPORT for them also doesn’t seem to add much value.

    aureleoules commented at 1:09 pm on April 16, 2022:
    Makes sense, I removed it
  35. util/check: Add CHECK_NONFATAL identity function, NONFATAL_UNREACHABLE AND UNREACHABLE macros ee02c8bd9a
  36. aureleoules force-pushed on Apr 16, 2022
  37. aureleoules renamed this:
    util/check: Add CHECK_NONFATAL identity function, NONFATAL_UNREACHABLE AND UNREACHABLE macros
    util/check: Add CHECK_NONFATAL identity function and NONFATAL_UNREACHABLE macro
    on Apr 16, 2022
  38. jonatack commented at 10:55 am on April 18, 2022: member
    ACK ee02c8bd9aedad8cfd3c2618035fe275da025fb9
  39. in src/rpc/util.cpp:798 in ee02c8bd9a
    793@@ -793,7 +794,7 @@ void RPCResult::ToSections(Sections& sections, const OuterType outer_type, const
    794         return;
    795     }
    796     case Type::ANY: {
    797-        CHECK_NONFATAL(false); // Only for testing
    798+        NONFATAL_UNREACHABLE(); // Only for testing
    799     }
    


    MarcoFalke commented at 9:37 am on April 24, 2022:

    This will also fix a warning on current master with gcc-12:

     0In file included from ./rpc/util.h:19,
     1                 from rpc/util.cpp:8:
     2rpc/util.cpp: In member function 'void RPCResult::ToSections(Sections&, OuterType, int) const':
     3./util/check.h:34:9: warning: this statement may fall through [-Wimplicit-fallthrough=]
     4   34 |         if (!(condition)) {                                       \
     5      |         ^~
     6rpc/util.cpp:796:9: note: in expansion of macro 'CHECK_NONFATAL'
     7  796 |         CHECK_NONFATAL(false); // Only for testing
     8      |         ^~~~~~~~~~~~~~
     9rpc/util.cpp:798:5: note: here
    10  798 |     case Type::NONE: {
    11      |     ^~~~
    
  40. in src/util/check.h:29 in ee02c8bd9a
    24+
    25+/** Helper for CHECK_NONFATAL() */
    26+template <typename T>
    27+T&& inline_check_non_fatal(T&& val, const char* file, int line, const char* func, const char* assertion)
    28+{
    29+    if (!(val)) {
    


    MarcoFalke commented at 9:53 am on April 24, 2022:
    0    if (!val) {
    

    nit: No need for ().

  41. in src/util/check.h:33 in ee02c8bd9a
    28+{
    29+    if (!(val)) {
    30+        throw NonFatalCheckError(
    31+            format_internal_error(assertion, file, line, func, PACKAGE_BUGREPORT));
    32+    }
    33+
    


    MarcoFalke commented at 9:53 am on April 24, 2022:
    nit: no need for newline
  42. MarcoFalke approved
  43. MarcoFalke commented at 9:54 am on April 24, 2022: member

    Looks like this also fixes a warning with gcc-12.

    ACK ee02c8bd9aedad8cfd3c2618035fe275da025fb9 🍨

    Signature:

     0-----BEGIN PGP SIGNED MESSAGE-----
     1Hash: SHA512
     2
     3ACK ee02c8bd9aedad8cfd3c2618035fe275da025fb9 🍨
     4-----BEGIN PGP SIGNATURE-----
     5
     6iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
     7pUjsdwwArddL1iP4wywDs5YPWiBmm1hOzJSazUrpOb4gx4plkEEHXOXvGqIIwoRQ
     8IPnUtiwBnIfZ7UDTHRUCgY8jeLNmlfZAtKRqd8n9V7fat6Uarmubynkz66O4C/pH
     9lPV6WRkkcby+KDy01EJW10vGa0NqLg9VoxWiTIfb5LwoiyqcxnLYvJ6/Ir30GYsn
    10cgG9pOIRhyYPYJQp79Q2R1fZmNe1Vi53RfxCBBkNXJI+tlMeCT7N8A6IHh239Dak
    11KPQP43FDbgkhTuwDmf+RNipSqyvH0sWRTqNCei9Q6WWqwGiiRMH883GWtWO392bR
    12gvkf+TmQeVoWqELVi+fFk7d+14zLJnnIvouMESjacwCEbkL5j5OKSw8WW6g0Uffb
    13y5VyRSEFV02OrxMHmKFKn3UEAQm551gnILgu0ERvkKopedGXxttNdvsnj9nuYiMj
    14IyPjD7MVuu+Ri6IaFtJ7jxCUGm+cPgei79bOuumTrRt/6g/+QZZnniZyhNx5oVHz
    15CKvY4MQC
    16=l4Sj
    17-----END PGP SIGNATURE-----
    
  44. MarcoFalke merged this on Apr 24, 2022
  45. MarcoFalke closed this on Apr 24, 2022

  46. sidhujag referenced this in commit 51ba4ab8cd on Apr 26, 2022
  47. aureleoules deleted the branch on May 20, 2022
  48. Fabcien referenced this in commit aac98988ac on Feb 3, 2023
  49. DrahtBot locked this on May 20, 2023

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2024-07-03 07:12 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me