debug.h 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #pragma once
  17. #include <iostream>
  18. #include <exception>
  19. #include <cassert>
  20. #include "gettime.h"
  21. #include "log.h"
  22. #ifdef _MSC_VER
  23. #define FUNCTION_NAME __FUNCTION__
  24. #else
  25. #define FUNCTION_NAME __PRETTY_FUNCTION__
  26. #endif
  27. // Whether to catch all std::exceptions.
  28. // When "catching", the program will abort with an error message.
  29. // In debug mode, leave these for the debugger and don't catch them.
  30. #ifdef NDEBUG
  31. #define CATCH_UNHANDLED_EXCEPTIONS 1
  32. #else
  33. #define CATCH_UNHANDLED_EXCEPTIONS 0
  34. #endif
  35. /* Abort program execution immediately
  36. */
  37. [[noreturn]] extern void fatal_error_fn(
  38. const char *msg, const char *file,
  39. unsigned int line, const char *function);
  40. #define FATAL_ERROR(msg) \
  41. fatal_error_fn((msg), __FILE__, __LINE__, FUNCTION_NAME)
  42. #define FATAL_ERROR_IF(expr, msg) \
  43. ((expr) \
  44. ? fatal_error_fn((msg), __FILE__, __LINE__, FUNCTION_NAME) \
  45. : (void)(0))
  46. /*
  47. sanity_check()
  48. Equivalent to assert() but persists in Release builds (i.e. when NDEBUG is
  49. defined)
  50. */
  51. [[noreturn]] extern void sanity_check_fn(
  52. const char *assertion, const char *file,
  53. unsigned int line, const char *function);
  54. #define SANITY_CHECK(expr) \
  55. ((expr) \
  56. ? (void)(0) \
  57. : sanity_check_fn(#expr, __FILE__, __LINE__, FUNCTION_NAME))
  58. #define sanity_check(expr) SANITY_CHECK(expr)
  59. std::string debug_describe_exc(const std::exception &e);
  60. void debug_set_exception_handler();
  61. /*
  62. These should be put into every thread
  63. */
  64. #if CATCH_UNHANDLED_EXCEPTIONS == 1
  65. #define BEGIN_DEBUG_EXCEPTION_HANDLER try {
  66. #define END_DEBUG_EXCEPTION_HANDLER \
  67. } catch (std::exception &e) { \
  68. std::string e_descr = debug_describe_exc(e); \
  69. errorstream << "An unhandled exception occurred: " \
  70. << e_descr << std::endl; \
  71. FATAL_ERROR(e_descr.c_str()); \
  72. }
  73. #else
  74. // Dummy ones
  75. #define BEGIN_DEBUG_EXCEPTION_HANDLER
  76. #define END_DEBUG_EXCEPTION_HANDLER
  77. #endif