1 // Copyright (c) 2007-2013 Hartmut Kaiser 2 // Copyright (c) 2011 Bryce Lelbach 3 // 4 // Distributed under the Boost Software License, Version 1.0. (See accompanying 5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 /// \file exception.hpp 8 9 #if !defined(HPX_EXCEPTION_MAR_24_2008_0929AM) 10 #define HPX_EXCEPTION_MAR_24_2008_0929AM 11 12 #include <hpx/config.hpp> 13 #include <hpx/error.hpp> 14 #include <hpx/error_code.hpp> 15 #include <hpx/exception_fwd.hpp> 16 #include <hpx/exception_info.hpp> 17 #include <hpx/runtime/naming_fwd.hpp> 18 19 #include <boost/system/error_code.hpp> 20 #include <boost/system/system_error.hpp> 21 22 #include <cstddef> 23 #include <cstdint> 24 #include <exception> 25 #include <string> 26 27 #include <hpx/config/warnings_prefix.hpp> 28 29 /////////////////////////////////////////////////////////////////////////////// 30 namespace hpx 31 { 32 /////////////////////////////////////////////////////////////////////////// 33 /// \brief A hpx::exception is the main exception type used by HPX to 34 /// report errors. 35 /// 36 /// The hpx::exception type is the main exception type used by HPX to 37 /// report errors. Any exceptions thrown by functions in the HPX library 38 /// are either of this type or of a type derived from it. This implies that 39 /// it is always safe to use this type only in catch statements guarding 40 /// HPX library calls. 41 class HPX_EXCEPTION_EXPORT exception : public boost::system::system_error 42 { 43 public: 44 /// Construct a hpx::exception from a \a hpx::error. 45 /// 46 /// \param e The parameter \p e holds the hpx::error code the new 47 /// exception should encapsulate. 48 explicit exception(error e = success); 49 50 /// Construct a hpx::exception from a boost#system_error. 51 explicit exception(boost::system::system_error const& e); 52 53 /// Construct a hpx::exception from a boost#system#error_code (this is 54 /// new for Boost V1.69). This constructor is required to compensate 55 /// for the changes introduced as a resolution to LWG3162 56 /// (https://cplusplus.github.io/LWG/issue3162). 57 explicit exception(boost::system::error_code const& e); 58 59 /// Construct a hpx::exception from a \a hpx::error and an error message. 60 /// 61 /// \param e The parameter \p e holds the hpx::error code the new 62 /// exception should encapsulate. 63 /// \param msg The parameter \p msg holds the error message the new 64 /// exception should encapsulate. 65 /// \param mode The parameter \p mode specifies whether the returned 66 /// hpx::error_code belongs to the error category 67 /// \a hpx_category (if mode is \a plain, this is the 68 /// default) or to the category \a hpx_category_rethrow 69 /// (if mode is \a rethrow). 70 exception(error e, char const* msg, throwmode mode = plain); 71 72 /// Construct a hpx::exception from a \a hpx::error and an error message. 73 /// 74 /// \param e The parameter \p e holds the hpx::error code the new 75 /// exception should encapsulate. 76 /// \param msg The parameter \p msg holds the error message the new 77 /// exception should encapsulate. 78 /// \param mode The parameter \p mode specifies whether the returned 79 /// hpx::error_code belongs to the error category 80 /// \a hpx_category (if mode is \a plain, this is the 81 /// default) or to the category \a hpx_category_rethrow 82 /// (if mode is \a rethrow). 83 exception(error e, std::string const& msg, throwmode mode = plain); 84 85 /// Destruct a hpx::exception 86 /// 87 /// \throws nothing 88 ~exception() throw(); 89 90 /// The function \a get_error() returns the hpx::error code stored 91 /// in the referenced instance of a hpx::exception. It returns 92 /// the hpx::error code this exception instance was constructed 93 /// from. 94 /// 95 /// \throws nothing 96 error get_error() const noexcept; 97 98 /// The function \a get_error_code() returns a hpx::error_code which 99 /// represents the same error condition as this hpx::exception instance. 100 /// 101 /// \param mode The parameter \p mode specifies whether the returned 102 /// hpx::error_code belongs to the error category 103 /// \a hpx_category (if mode is \a plain, this is the 104 /// default) or to the category \a hpx_category_rethrow 105 /// (if mode is \a rethrow). 106 error_code get_error_code(throwmode mode = plain) const noexcept; 107 }; 108 109 /////////////////////////////////////////////////////////////////////////// 110 /// \brief A hpx::thread_interrupted is the exception type used by HPX to 111 /// interrupt a running HPX thread. 112 /// 113 /// The \a hpx::thread_interrupted type is the exception type used by HPX to 114 /// interrupt a running thread. 115 /// 116 /// A running thread can be interrupted by invoking the interrupt() member 117 /// function of the corresponding hpx::thread object. When the interrupted 118 /// thread next executes one of the specified interruption points (or if it 119 /// is currently blocked whilst executing one) with interruption enabled, 120 /// then a hpx::thread_interrupted exception will be thrown in the interrupted 121 /// thread. If not caught, this will cause the execution of the interrupted 122 /// thread to terminate. As with any other exception, the stack will be 123 /// unwound, and destructors for objects of automatic storage duration will 124 /// be executed. 125 /// 126 /// If a thread wishes to avoid being interrupted, it can create an instance 127 /// of \a hpx::this_thread::disable_interruption. Objects of this class disable 128 /// interruption for the thread that created them on construction, and 129 /// restore the interruption state to whatever it was before on destruction. 130 /// 131 /// \code 132 /// void f() 133 /// { 134 /// // interruption enabled here 135 /// { 136 /// hpx::this_thread::disable_interruption di; 137 /// // interruption disabled 138 /// { 139 /// hpx::this_thread::disable_interruption di2; 140 /// // interruption still disabled 141 /// } // di2 destroyed, interruption state restored 142 /// // interruption still disabled 143 /// } // di destroyed, interruption state restored 144 /// // interruption now enabled 145 /// } 146 /// \endcode 147 /// 148 /// The effects of an instance of \a hpx::this_thread::disable_interruption can be 149 /// temporarily reversed by constructing an instance of 150 /// \a hpx::this_thread::restore_interruption, passing in the 151 /// \a hpx::this_thread::disable_interruption object in question. This will restore 152 /// the interruption state to what it was when the 153 /// \a hpx::this_thread::disable_interruption 154 /// object was constructed, and then disable interruption again when the 155 /// \a hpx::this_thread::restore_interruption object is destroyed. 156 /// 157 /// \code 158 /// void g() 159 /// { 160 /// // interruption enabled here 161 /// { 162 /// hpx::this_thread::disable_interruption di; 163 /// // interruption disabled 164 /// { 165 /// hpx::this_thread::restore_interruption ri(di); 166 /// // interruption now enabled 167 /// } // ri destroyed, interruption disable again 168 /// } // di destroyed, interruption state restored 169 /// // interruption now enabled 170 /// } 171 /// \endcode 172 /// 173 /// At any point, the interruption state for the current thread can be 174 /// queried by calling \a hpx::this_thread::interruption_enabled(). 175 struct HPX_EXCEPTION_EXPORT thread_interrupted : std::exception {}; 176 177 /// \cond NODETAIL 178 namespace detail 179 { 180 struct HPX_EXCEPTION_EXPORT std_exception : std::exception 181 { 182 private: 183 std::string what_; 184 185 public: std_exceptionhpx::detail::std_exception186 explicit std_exception(std::string const& w) 187 : what_(w) 188 {} 189 ~std_exceptionhpx::detail::std_exception190 ~std_exception() throw() {} 191 whathpx::detail::std_exception192 const char* what() const throw() 193 { 194 return what_.c_str(); 195 } 196 }; 197 198 struct HPX_EXCEPTION_EXPORT bad_alloc : std::bad_alloc 199 { 200 private: 201 std::string what_; 202 203 public: bad_allochpx::detail::bad_alloc204 explicit bad_alloc(std::string const& w) 205 : what_(w) 206 {} 207 ~bad_allochpx::detail::bad_alloc208 ~bad_alloc() throw() {} 209 whathpx::detail::bad_alloc210 const char* what() const throw() 211 { 212 return what_.c_str(); 213 } 214 }; 215 216 struct HPX_EXCEPTION_EXPORT bad_exception : std::bad_exception 217 { 218 private: 219 std::string what_; 220 221 public: bad_exceptionhpx::detail::bad_exception222 explicit bad_exception(std::string const& w) 223 : what_(w) 224 {} 225 ~bad_exceptionhpx::detail::bad_exception226 ~bad_exception() throw() {} 227 whathpx::detail::bad_exception228 const char* what() const throw() 229 { 230 return what_.c_str(); 231 } 232 }; 233 234 struct HPX_EXCEPTION_EXPORT bad_cast : std::bad_cast 235 { 236 private: 237 std::string what_; 238 239 public: bad_casthpx::detail::bad_cast240 explicit bad_cast(std::string const& w) 241 : what_(w) 242 {} 243 ~bad_casthpx::detail::bad_cast244 ~bad_cast() throw() {} 245 whathpx::detail::bad_cast246 const char* what() const throw() 247 { 248 return what_.c_str(); 249 } 250 }; 251 252 struct HPX_EXCEPTION_EXPORT bad_typeid : std::bad_typeid 253 { 254 private: 255 std::string what_; 256 257 public: bad_typeidhpx::detail::bad_typeid258 explicit bad_typeid(std::string const& w) 259 : what_(w) 260 {} 261 ~bad_typeidhpx::detail::bad_typeid262 ~bad_typeid() throw() {} 263 whathpx::detail::bad_typeid264 const char* what() const throw() 265 { 266 return what_.c_str(); 267 } 268 }; 269 270 /////////////////////////////////////////////////////////////////////// 271 // Stores the information about the locality id the exception has been 272 // raised on. This information will show up in error messages under the 273 // [locality] tag. 274 HPX_DEFINE_ERROR_INFO(throw_locality, std::uint32_t); 275 276 // Stores the information about the hostname of the locality the exception 277 // has been raised on. This information will show up in error messages 278 // under the [hostname] tag. 279 HPX_DEFINE_ERROR_INFO(throw_hostname, std::string); 280 281 // Stores the information about the pid of the OS process the exception 282 // has been raised on. This information will show up in error messages 283 // under the [pid] tag. 284 HPX_DEFINE_ERROR_INFO(throw_pid, std::int64_t); 285 286 // Stores the information about the shepherd thread the exception has been 287 // raised on. This information will show up in error messages under the 288 // [shepherd] tag. 289 HPX_DEFINE_ERROR_INFO(throw_shepherd, std::size_t); 290 291 // Stores the information about the HPX thread the exception has been 292 // raised on. This information will show up in error messages under the 293 // [thread_id] tag. 294 HPX_DEFINE_ERROR_INFO(throw_thread_id, std::size_t); 295 296 // Stores the information about the HPX thread name the exception has been 297 // raised on. This information will show up in error messages under the 298 // [thread_name] tag. 299 HPX_DEFINE_ERROR_INFO(throw_thread_name, std::string); 300 301 // Stores the information about the function name the exception has been 302 // raised in. This information will show up in error messages under the 303 // [function] tag. 304 HPX_DEFINE_ERROR_INFO(throw_function, std::string); 305 306 // Stores the information about the source file name the exception has 307 // been raised in. This information will show up in error messages under 308 // the [file] tag. 309 HPX_DEFINE_ERROR_INFO(throw_file, std::string); 310 311 // Stores the information about the source file line number the exception 312 // has been raised at. This information will show up in error messages 313 // under the [line] tag. 314 HPX_DEFINE_ERROR_INFO(throw_line, long); 315 316 // Stores the information about the stack backtrace at the point the 317 // exception has been raised at. This information will show up in error 318 // messages under the [stack_trace] tag. 319 HPX_DEFINE_ERROR_INFO(throw_stacktrace, std::string); 320 321 // Stores the full execution environment of the locality the exception 322 // has been raised in. This information will show up in error messages 323 // under the [env] tag. 324 HPX_DEFINE_ERROR_INFO(throw_env, std::string); 325 326 // Stores the full HPX configuration information of the locality the 327 // exception has been raised in. This information will show up in error 328 // messages under the [config] tag. 329 HPX_DEFINE_ERROR_INFO(throw_config, std::string); 330 331 // Stores the current runtime state. This information will show up in 332 // error messages under the [state] tag. 333 HPX_DEFINE_ERROR_INFO(throw_state, std::string); 334 335 // Stores additional auxiliary information (such as information about 336 // the current parcel). This information will show up in error messages 337 // under the [auxinfo] tag. 338 HPX_DEFINE_ERROR_INFO(throw_auxinfo, std::string); 339 340 // construct an exception, internal helper 341 template <typename Exception> 342 HPX_EXPORT std::exception_ptr 343 construct_exception(Exception const& e, 344 std::string const& func, std::string const& file, long line, 345 std::string const& back_trace = "", std::uint32_t node = 0, 346 std::string const& hostname = "", std::int64_t pid = -1, 347 std::size_t shepherd = ~0, std::size_t thread_id = 0, 348 std::string const& thread_name = "", 349 std::string const& env = "", std::string const& config = "", 350 std::string const& state = "", std::string const& auxinfo = ""); 351 352 template <typename Exception> 353 HPX_EXPORT std::exception_ptr 354 construct_lightweight_exception(Exception const& e); 355 356 // HPX_ASSERT handler 357 HPX_NORETURN HPX_EXPORT 358 void assertion_failed(char const* expr, char const* function, 359 char const* file, long line); 360 361 // HPX_ASSERT_MSG handler 362 HPX_NORETURN HPX_EXPORT 363 void assertion_failed_msg(char const* msg, char const* expr, 364 char const* function, char const* file, long line); 365 366 // If backtrace support is enabled, this function returns the current 367 // stack backtrace, otherwise it will return an empty string. 368 HPX_EXPORT std::string backtrace( 369 std::size_t frames = HPX_HAVE_THREAD_BACKTRACE_DEPTH); 370 HPX_EXPORT std::string backtrace_direct( 371 std::size_t frames = HPX_HAVE_THREAD_BACKTRACE_DEPTH); 372 373 // Portably extract the current execution environment 374 HPX_EXPORT std::string get_execution_environment(); 375 376 // Report an early or late exception and locally abort execution. There 377 // isn't anything more we could do. 378 HPX_NORETURN HPX_EXPORT void report_exception_and_terminate( 379 std::exception_ptr const&); 380 HPX_NORETURN HPX_EXPORT void report_exception_and_terminate( 381 hpx::exception const&); 382 383 // Report an early or late exception and locally exit execution. There 384 // isn't anything more we could do. The exception will be re-thrown 385 // from hpx::init 386 HPX_EXPORT void report_exception_and_continue(std::exception_ptr const&); 387 HPX_EXPORT void report_exception_and_continue(hpx::exception const&); 388 } 389 /// \endcond 390 391 /////////////////////////////////////////////////////////////////////////// 392 /// \brief Extract the diagnostic information embedded in the given 393 /// exception and return a string holding a formatted message. 394 /// 395 /// The function \a hpx::diagnostic_information can be used to extract all 396 /// diagnostic information stored in the given exception instance as a 397 /// formatted string. This simplifies debug output as it composes the 398 /// diagnostics into one, easy to use function call. This includes 399 /// the name of the source file and line number, the sequence number of the 400 /// OS-thread and the HPX-thread id, the locality id and the stack backtrace 401 /// of the point where the original exception was thrown. 402 /// 403 /// \param xi The parameter \p e will be inspected for all diagnostic 404 /// information elements which have been stored at the point 405 /// where the exception was thrown. This parameter can be one 406 /// of the following types: \a hpx::exception_info, 407 /// \a hpx::error_code, \a std::exception, or 408 /// \a std::exception_ptr. 409 /// 410 /// \returns The formatted string holding all of the available 411 /// diagnostic information stored in the given exception 412 /// instance. 413 /// 414 /// \throws std#bad_alloc (if any of the required allocation operations 415 /// fail) 416 /// 417 /// \see \a hpx::get_error_locality_id(), \a hpx::get_error_host_name(), 418 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 419 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 420 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 421 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 422 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 423 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 424 /// \a hpx::get_error_state() 425 /// 426 HPX_EXPORT std::string diagnostic_information(exception_info const& xi); 427 428 /// \cond NOINTERNAL 429 template <typename E> diagnostic_information(E const & e)430 std::string diagnostic_information(E const& e) 431 { 432 return invoke_with_exception_info(e, [](exception_info const* xi) { 433 return xi ? diagnostic_information(*xi) : std::string("<unknown>"); 434 }); 435 } 436 /// \endcond 437 438 /////////////////////////////////////////////////////////////////////////// 439 // Extract elements of the diagnostic information embedded in the given 440 // exception. 441 442 /// \brief Return the error message of the thrown exception. 443 /// 444 /// The function \a hpx::get_error_what can be used to extract the 445 /// diagnostic information element representing the error message as stored 446 /// in the given exception instance. 447 /// 448 /// \param xi The parameter \p e will be inspected for the requested 449 /// diagnostic information elements which have been stored at 450 /// the point where the exception was thrown. This parameter 451 /// can be one of the following types: \a hpx::exception_info, 452 /// \a hpx::error_code, \a std::exception, or 453 /// \a std::exception_ptr. 454 /// 455 /// \returns The error message stored in the exception 456 /// If the exception instance does not hold 457 /// this information, the function will return an empty string. 458 /// 459 /// \throws std#bad_alloc (if one of the required allocations fails) 460 /// 461 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 462 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 463 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 464 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 465 /// \a hpx::get_error_thread_description(), \a hpx::get_error() 466 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 467 /// \a hpx::get_error_config(), \a hpx::get_error_state() 468 /// 469 HPX_EXPORT std::string get_error_what(exception_info const& xi); 470 471 /// \cond NOINTERNAL 472 template <typename E> get_error_what(E const & e)473 std::string get_error_what(E const& e) 474 { 475 return invoke_with_exception_info(e, [](exception_info const* xi) { 476 return xi ? get_error_what(*xi) : std::string("<unknown>"); 477 }); 478 } 479 get_error_what(hpx::error_code const & e)480 inline std::string get_error_what(hpx::error_code const& e) 481 { 482 // if this is a lightweight error_code, return canned response 483 if (e.category() == hpx::get_lightweight_hpx_category()) 484 return e.message(); 485 486 return get_error_what<hpx::error_code>(e); 487 } 488 get_error_what(std::exception const & e)489 inline std::string get_error_what(std::exception const& e) 490 { 491 return e.what(); 492 } 493 /// \endcond 494 495 /// \brief Return the locality id where the exception was thrown. 496 /// 497 /// The function \a hpx::get_error_locality_id can be used to extract the 498 /// diagnostic information element representing the locality id as stored 499 /// in the given exception instance. 500 /// 501 /// \param xi The parameter \p e will be inspected for the requested 502 /// diagnostic information elements which have been stored at 503 /// the point where the exception was thrown. This parameter 504 /// can be one of the following types: \a hpx::exception_info, 505 /// \a hpx::error_code, \a std::exception, or 506 /// \a std::exception_ptr. 507 /// 508 /// \returns The locality id of the locality where the exception was 509 /// thrown. If the exception instance does not hold 510 /// this information, the function will return 511 /// \a hpx::naming#invalid_locality_id. 512 /// 513 /// \throws nothing 514 /// 515 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 516 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 517 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 518 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 519 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 520 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 521 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 522 /// \a hpx::get_error_state() 523 /// 524 HPX_EXPORT std::uint32_t get_error_locality_id(hpx::exception_info const& xi); 525 526 /// \cond NOINTERNAL 527 template <typename E> get_error_locality_id(E const & e)528 std::uint32_t get_error_locality_id(E const& e) 529 { 530 return invoke_with_exception_info(e, [](exception_info const* xi) { 531 return xi ? get_error_locality_id(*xi) : naming::invalid_locality_id; 532 }); 533 } 534 /// \endcond 535 536 /// \brief Return the locality id where the exception was thrown. 537 /// 538 /// The function \a hpx::get_error can be used to extract the 539 /// diagnostic information element representing the error value code as 540 /// stored in the given exception instance. 541 /// 542 /// \param e The parameter \p e will be inspected for the requested 543 /// diagnostic information elements which have been stored at 544 /// the point where the exception was thrown. This parameter 545 /// can be one of the following types: \a hpx::exception, 546 /// \a hpx::error_code, or \a std::exception_ptr. 547 /// 548 /// \returns The error value code of the locality where the exception was 549 /// thrown. If the exception instance does not hold 550 /// this information, the function will return 551 /// \a hpx::naming#invalid_locality_id. 552 /// 553 /// \throws nothing 554 /// 555 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 556 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 557 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 558 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 559 /// \a hpx::get_error_thread_description(), 560 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 561 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 562 /// \a hpx::get_error_state() 563 /// 564 HPX_EXPORT error get_error(hpx::exception const& e); 565 566 /// \copydoc get_error(hpx::exception const& e) 567 HPX_EXPORT error get_error(hpx::error_code const& e); 568 569 /// \cond NOINTERNAL 570 HPX_EXPORT error get_error(std::exception_ptr const& e); 571 /// \endcond 572 573 /// \brief Return the hostname of the locality where the exception was 574 /// thrown. 575 /// 576 /// The function \a hpx::get_error_host_name can be used to extract the 577 /// diagnostic information element representing the host name as stored in 578 /// the given exception instance. 579 /// 580 /// \param xi The parameter \p e will be inspected for the requested 581 /// diagnostic information elements which have been stored at 582 /// the point where the exception was thrown. This parameter 583 /// can be one of the following types: \a hpx::exception_info, 584 /// \a hpx::error_code, \a std::exception, or 585 /// \a std::exception_ptr. 586 /// 587 /// \returns The hostname of the locality where the exception was 588 /// thrown. If the exception instance does not hold 589 /// this information, the function will return and empty string. 590 /// 591 /// \throws std#bad_alloc (if one of the required allocations fails) 592 /// 593 /// \see \a hpx::diagnostic_information() 594 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 595 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 596 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 597 /// \a hpx::get_error_thread_description(), \a hpx::get_error() 598 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 599 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 600 /// \a hpx::get_error_state() 601 /// 602 HPX_EXPORT std::string get_error_host_name(hpx::exception_info const& xi); 603 604 /// \cond NOINTERNAL 605 template <typename E> get_error_host_name(E const & e)606 std::string get_error_host_name(E const& e) 607 { 608 return invoke_with_exception_info(e, [](exception_info const* xi) { 609 return xi ? get_error_host_name(*xi) : std::string(); 610 }); 611 } 612 /// \endcond 613 614 /// \brief Return the (operating system) process id of the locality where 615 /// the exception was thrown. 616 /// 617 /// The function \a hpx::get_error_process_id can be used to extract the 618 /// diagnostic information element representing the process id as stored in 619 /// the given exception instance. 620 /// 621 /// \returns The process id of the OS-process which threw the exception 622 /// If the exception instance does not hold 623 /// this information, the function will return 0. 624 /// 625 /// \param xi The parameter \p e will be inspected for the requested 626 /// diagnostic information elements which have been stored at 627 /// the point where the exception was thrown. This parameter 628 /// can be one of the following types: \a hpx::exception_info, 629 /// \a hpx::error_code, \a std::exception, or 630 /// \a std::exception_ptr. 631 /// 632 /// \throws nothing 633 /// 634 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 635 /// \a hpx::get_error_function_name(), 636 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 637 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 638 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 639 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 640 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 641 /// \a hpx::get_error_state() 642 /// 643 HPX_EXPORT std::int64_t get_error_process_id(hpx::exception_info const& xi); 644 645 /// \cond NOINTERNAL 646 template <typename E> get_error_process_id(E const & e)647 std::int64_t get_error_process_id(E const& e) 648 { 649 return invoke_with_exception_info(e, [](exception_info const* xi) { 650 return xi ? get_error_process_id(*xi) : -1; 651 }); 652 } 653 /// \endcond 654 655 /// \brief Return the environment of the OS-process at the point the 656 /// exception was thrown. 657 /// 658 /// The function \a hpx::get_error_env can be used to extract the 659 /// diagnostic information element representing the environment of the 660 /// OS-process collected at the point the exception was thrown. 661 /// 662 /// \returns The environment from the point the exception was 663 /// thrown. If the exception instance does not hold 664 /// this information, the function will return an empty string. 665 /// 666 /// \param xi The parameter \p e will be inspected for the requested 667 /// diagnostic information elements which have been stored at 668 /// the point where the exception was thrown. This parameter 669 /// can be one of the following types: \a hpx::exception_info, 670 /// \a hpx::error_code, \a std::exception, or 671 /// \a std::exception_ptr. 672 /// 673 /// \throws std#bad_alloc (if one of the required allocations fails) 674 /// 675 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 676 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 677 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 678 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 679 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 680 /// \a hpx::get_error_backtrace(), 681 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 682 /// \a hpx::get_error_state() 683 /// 684 HPX_EXPORT std::string get_error_env(hpx::exception_info const& xi); 685 686 /// \cond NOINTERNAL 687 template <typename E> get_error_env(E const & e)688 std::string get_error_env(E const& e) 689 { 690 return invoke_with_exception_info(e, [](exception_info const* xi) { 691 return xi ? get_error_env(*xi) : std::string("<unknown>"); 692 }); 693 } 694 /// \endcond 695 696 /// \brief Return the function name from which the exception was thrown. 697 /// 698 /// The function \a hpx::get_error_function_name can be used to extract the 699 /// diagnostic information element representing the name of the function 700 /// as stored in the given exception instance. 701 /// 702 /// \returns The name of the function from which the exception was 703 /// thrown. If the exception instance does not hold 704 /// this information, the function will return an empty string. 705 /// 706 /// \param xi The parameter \p e will be inspected for the requested 707 /// diagnostic information elements which have been stored at 708 /// the point where the exception was thrown. This parameter 709 /// can be one of the following types: \a hpx::exception_info, 710 /// \a hpx::error_code, \a std::exception, or 711 /// \a std::exception_ptr. 712 /// 713 /// \throws std#bad_alloc (if one of the required allocations fails) 714 /// 715 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 716 /// \a hpx::get_error_process_id() 717 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 718 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 719 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 720 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 721 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 722 /// \a hpx::get_error_state() 723 /// 724 HPX_EXPORT std::string get_error_function_name(hpx::exception_info const& xi); 725 726 /// \cond NOINTERNAL 727 template <typename E> get_error_function_name(E const & e)728 std::string get_error_function_name(E const& e) 729 { 730 return invoke_with_exception_info(e, [](exception_info const* xi) { 731 return xi ? get_error_function_name(*xi) : std::string(); 732 }); 733 } 734 /// \endcond 735 736 /// \brief Return the stack backtrace from the point the exception was thrown. 737 /// 738 /// The function \a hpx::get_error_backtrace can be used to extract the 739 /// diagnostic information element representing the stack backtrace 740 /// collected at the point the exception was thrown. 741 /// 742 /// \returns The stack back trace from the point the exception was 743 /// thrown. If the exception instance does not hold 744 /// this information, the function will return an empty string. 745 /// 746 /// \param xi The parameter \p e will be inspected for the requested 747 /// diagnostic information elements which have been stored at 748 /// the point where the exception was thrown. This parameter 749 /// can be one of the following types: \a hpx::exception_info, 750 /// \a hpx::error_code, \a std::exception, or 751 /// \a std::exception_ptr. 752 /// 753 /// \throws std#bad_alloc (if one of the required allocations fails) 754 /// 755 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 756 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 757 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 758 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 759 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 760 /// \a hpx::get_error_env(), 761 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 762 /// \a hpx::get_error_state() 763 /// 764 HPX_EXPORT std::string get_error_backtrace(hpx::exception_info const& xi); 765 766 /// \cond NOINTERNAL 767 template <typename E> get_error_backtrace(E const & e)768 std::string get_error_backtrace(E const& e) 769 { 770 return invoke_with_exception_info(e, [](exception_info const* xi) { 771 return xi ? get_error_backtrace(*xi) : std::string(); 772 }); 773 } 774 /// \endcond 775 776 /// \brief Return the (source code) file name of the function from which 777 /// the exception was thrown. 778 /// 779 /// The function \a hpx::get_error_file_name can be used to extract the 780 /// diagnostic information element representing the name of the source file 781 /// as stored in the given exception instance. 782 /// 783 /// \returns The name of the source file of the function from which the 784 /// exception was thrown. If the exception instance does 785 /// not hold this information, the function will return an empty 786 /// string. 787 /// 788 /// \param xi The parameter \p e will be inspected for the requested 789 /// diagnostic information elements which have been stored at 790 /// the point where the exception was thrown. This parameter 791 /// can be one of the following types: \a hpx::exception_info, 792 /// \a hpx::error_code, \a std::exception, or 793 /// \a std::exception_ptr. 794 /// 795 /// \throws std#bad_alloc (if one of the required allocations fails) 796 /// 797 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 798 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 799 /// \a hpx::get_error_line_number(), 800 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 801 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 802 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 803 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 804 /// \a hpx::get_error_state() 805 /// 806 HPX_EXPORT std::string get_error_file_name(hpx::exception_info const& xi); 807 808 /// \cond NOINTERNAL 809 template <typename E> get_error_file_name(E const & e)810 std::string get_error_file_name(E const& e) 811 { 812 return invoke_with_exception_info(e, [](exception_info const* xi) { 813 return xi ? get_error_file_name(*xi) : std::string("<unknown>"); 814 }); 815 } 816 /// \endcond 817 818 /// \brief Return the line number in the (source code) file of the function 819 /// from which the exception was thrown. 820 /// 821 /// The function \a hpx::get_error_line_number can be used to extract the 822 /// diagnostic information element representing the line number 823 /// as stored in the given exception instance. 824 /// 825 /// \returns The line number of the place where the exception was 826 /// thrown. If the exception instance does not hold 827 /// this information, the function will return -1. 828 /// 829 /// \param xi The parameter \p e will be inspected for the requested 830 /// diagnostic information elements which have been stored at 831 /// the point where the exception was thrown. This parameter 832 /// can be one of the following types: \a hpx::exception_info, 833 /// \a hpx::error_code, \a std::exception, or 834 /// \a std::exception_ptr. 835 /// 836 /// \throws nothing 837 /// 838 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 839 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 840 /// \a hpx::get_error_file_name() 841 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 842 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 843 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 844 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 845 /// \a hpx::get_error_state() 846 /// 847 HPX_EXPORT long get_error_line_number(hpx::exception_info const& xi); 848 849 /// \cond NOINTERNAL 850 template <typename E> get_error_line_number(E const & e)851 long get_error_line_number(E const& e) 852 { 853 return invoke_with_exception_info(e, [](exception_info const* xi) { 854 return xi ? get_error_line_number(*xi) : -1; 855 }); 856 } 857 /// \endcond 858 859 /// \brief Return the sequence number of the OS-thread used to execute 860 /// HPX-threads from which the exception was thrown. 861 /// 862 /// The function \a hpx::get_error_os_thread can be used to extract the 863 /// diagnostic information element representing the sequence number of the 864 /// OS-thread as stored in the given exception instance. 865 /// 866 /// \returns The sequence number of the OS-thread used to execute the 867 /// HPX-thread from which the exception was 868 /// thrown. If the exception instance does not hold 869 /// this information, the function will return std::size(-1). 870 /// 871 /// \param xi The parameter \p e will be inspected for the requested 872 /// diagnostic information elements which have been stored at 873 /// the point where the exception was thrown. This parameter 874 /// can be one of the following types: \a hpx::exception_info, 875 /// \a hpx::error_code, \a std::exception, or 876 /// \a std::exception_ptr. 877 /// 878 /// \throws nothing 879 /// 880 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 881 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 882 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 883 /// \a hpx::get_error_thread_id(), 884 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 885 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 886 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 887 /// \a hpx::get_error_state() 888 /// 889 HPX_EXPORT std::size_t get_error_os_thread(hpx::exception_info const& xi); 890 891 /// \cond NOINTERNAL 892 template <typename E> get_error_os_thread(E const & e)893 std::size_t get_error_os_thread(E const& e) 894 { 895 return invoke_with_exception_info(e, [](exception_info const* xi) { 896 return xi ? get_error_os_thread(*xi) : std::size_t(-1); 897 }); 898 } 899 /// \endcond 900 901 /// \brief Return the unique thread id of the HPX-thread from which the 902 /// exception was thrown. 903 /// 904 /// The function \a hpx::get_error_thread_id can be used to extract the 905 /// diagnostic information element representing the HPX-thread id 906 /// as stored in the given exception instance. 907 /// 908 /// \returns The unique thread id of the HPX-thread from which the 909 /// exception was thrown. If the exception instance 910 /// does not hold this information, the function will return 911 /// std::size_t(0). 912 /// 913 /// \param xi The parameter \p e will be inspected for the requested 914 /// diagnostic information elements which have been stored at 915 /// the point where the exception was thrown. This parameter 916 /// can be one of the following types: \a hpx::exception_info, 917 /// \a hpx::error_code, \a std::exception, or 918 /// \a std::exception_ptr. 919 /// 920 /// \throws nothing 921 /// 922 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 923 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 924 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 925 /// \a hpx::get_error_os_thread() 926 /// \a hpx::get_error_thread_description(), \a hpx::get_error(), 927 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 928 /// \a hpx::get_error_what(), \a hpx::get_error_config(), 929 /// \a hpx::get_error_state() 930 /// 931 HPX_EXPORT std::size_t get_error_thread_id(hpx::exception_info const& xi); 932 933 /// \cond NOINTERNAL 934 template <typename E> get_error_thread_id(E const & e)935 std::size_t get_error_thread_id(E const& e) 936 { 937 return invoke_with_exception_info(e, [](exception_info const* xi) { 938 return xi ? get_error_thread_id(*xi) : std::size_t(-1); 939 }); 940 } 941 /// \endcond 942 943 /// \brief Return any additionally available thread description of the 944 /// HPX-thread from which the exception was thrown. 945 /// 946 /// The function \a hpx::get_error_thread_description can be used to extract the 947 /// diagnostic information element representing the additional thread 948 /// description as stored in the given exception instance. 949 /// 950 /// \returns Any additionally available thread description of the 951 /// HPX-thread from which the exception was 952 /// thrown. If the exception instance does not hold 953 /// this information, the function will return an empty string. 954 /// 955 /// \param xi The parameter \p e will be inspected for the requested 956 /// diagnostic information elements which have been stored at 957 /// the point where the exception was thrown. This parameter 958 /// can be one of the following types: \a hpx::exception_info, 959 /// \a hpx::error_code, \a std::exception, or 960 /// \a std::exception_ptr. 961 /// 962 /// \throws std#bad_alloc (if one of the required allocations fails) 963 /// 964 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 965 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 966 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 967 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 968 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 969 /// \a hpx::get_error(), \a hpx::get_error_state(), 970 /// \a hpx::get_error_what(), \a hpx::get_error_config() 971 /// 972 HPX_EXPORT std::string get_error_thread_description(hpx::exception_info const& xi); 973 974 /// \cond NOINTERNAL 975 template <typename E> get_error_thread_description(E const & e)976 std::string get_error_thread_description(E const& e) 977 { 978 return invoke_with_exception_info(e, [](exception_info const* xi) { 979 return xi ? get_error_thread_description(*xi) : std::string(); 980 }); 981 } 982 /// \endcond 983 984 /// \brief Return the HPX configuration information point from which the 985 /// exception was thrown. 986 /// 987 /// The function \a hpx::get_error_config can be used to extract the 988 /// HPX configuration information element representing the full HPX 989 /// configuration information as stored in the given exception instance. 990 /// 991 /// \returns Any additionally available HPX configuration information 992 /// the point from which the exception was 993 /// thrown. If the exception instance does not hold 994 /// this information, the function will return an empty string. 995 /// 996 /// \param xi The parameter \p e will be inspected for the requested 997 /// diagnostic information elements which have been stored at 998 /// the point where the exception was thrown. This parameter 999 /// can be one of the following types: \a hpx::exception_info, 1000 /// \a hpx::error_code, \a std::exception, or 1001 /// \a std::exception_ptr. 1002 /// 1003 /// \throws std#bad_alloc (if one of the required allocations fails) 1004 /// 1005 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 1006 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 1007 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 1008 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 1009 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 1010 /// \a hpx::get_error(), \a hpx::get_error_state() 1011 /// \a hpx::get_error_what(), \a hpx::get_error_thread_description() 1012 /// 1013 HPX_EXPORT std::string get_error_config(hpx::exception_info const& xi); 1014 1015 /// \cond NOINTERNAL 1016 template <typename E> get_error_config(E const & e)1017 std::string get_error_config(E const& e) 1018 { 1019 return invoke_with_exception_info(e, [](exception_info const* xi) { 1020 return xi ? get_error_config(*xi) : std::string(); 1021 }); 1022 } 1023 /// \endcond 1024 1025 /// \brief Return the HPX runtime state information at which the exception 1026 /// was thrown. 1027 /// 1028 /// The function \a hpx::get_error_state can be used to extract the 1029 /// HPX runtime state information element representing the state the 1030 /// runtime system is currently in as stored in the given exception 1031 /// instance. 1032 /// 1033 /// \returns The point runtime state at the point at which the exception 1034 /// was thrown. If the exception instance does not hold 1035 /// this information, the function will return an empty string. 1036 /// 1037 /// \param xi The parameter \p e will be inspected for the requested 1038 /// diagnostic information elements which have been stored at 1039 /// the point where the exception was thrown. This parameter 1040 /// can be one of the following types: \a hpx::exception_info, 1041 /// \a hpx::error_code, \a std::exception, or 1042 /// \a std::exception_ptr. 1043 /// 1044 /// \throws std#bad_alloc (if one of the required allocations fails) 1045 /// 1046 /// \see \a hpx::diagnostic_information(), \a hpx::get_error_host_name(), 1047 /// \a hpx::get_error_process_id(), \a hpx::get_error_function_name(), 1048 /// \a hpx::get_error_file_name(), \a hpx::get_error_line_number(), 1049 /// \a hpx::get_error_os_thread(), \a hpx::get_error_thread_id(), 1050 /// \a hpx::get_error_backtrace(), \a hpx::get_error_env(), 1051 /// \a hpx::get_error(), 1052 /// \a hpx::get_error_what(), \a hpx::get_error_thread_description() 1053 /// 1054 HPX_EXPORT std::string get_error_state(hpx::exception_info const& xi); 1055 1056 /// \cond NOINTERNAL 1057 template <typename E> get_error_state(E const & e)1058 std::string get_error_state(E const& e) 1059 { 1060 return invoke_with_exception_info(e, [](exception_info const* xi) { 1061 return xi ? get_error_state(*xi) : std::string(); 1062 }); 1063 } 1064 /// \endcond 1065 1066 /////////////////////////////////////////////////////////////////////////// 1067 // \cond NOINTERNAL 1068 // forwarder for HPX_ASSERT handler 1069 HPX_NORETURN HPX_EXPORT 1070 void assertion_failed(char const* expr, char const* function, 1071 char const* file, long line); 1072 1073 // forwarder for HPX_ASSERT_MSG handler 1074 HPX_NORETURN HPX_EXPORT 1075 void assertion_failed_msg(char const* msg, char const* expr, 1076 char const* function, char const* file, long line); 1077 1078 // For testing purposes we sometime expect to see exceptions, allow those 1079 // to go through without attaching a debugger. 1080 // 1081 // This should be used carefully as it disables the possible attaching of 1082 // a debugger for all exceptions, not only the expected ones. 1083 HPX_EXPORT bool expect_exception(bool flag = true); 1084 /// \endcond 1085 } 1086 1087 #include <hpx/throw_exception.hpp> 1088 1089 #include <hpx/config/warnings_suffix.hpp> 1090 1091 #endif 1092