You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The issue relates to an overhaul of the exception handling design in the libsyclinterface helper library.
Background
libsyclinterface tries to follow the so-calledAbrahams Guarantees design for exception handling. Our intent is to ensure:
No throw: No C++ exceptions will be raised inside libsyclinterface, i.e., all exceptions should be caught.
Basic exception safety: No resources should be leaked in the case of an exception. All previously allocated resources in the function prior to encountering an exception should get freed inside the catch block. (Note: Klockwork is able to catch these issues.)
Strong exception safety: Rollback of any externally visible side-effects. If an argument passed into a function was updated prior to encountering the exception, it should be reverted back to its original value.
No guarantees: 😃
Requirements
Ensure proper exception safety is implemented in libsyclinterface by auditing the code and adding negative test cases.
Make the handling of exceptions more informative and user configurable.
Currently, libsyclinterface only prints out the exception message inside a catch block. The behavior is very rudimentary and not configurable at all. Instead, we can introduce a handler function that can log exceptions in different ways, such as print out messages with different levels of verbosity or even write them to a file. The handler function should be added to the helper directory.
We can use a library such as Boost Log for this purpose. Boost logs allows creating a global logger that I believe is thread safe. Most probably we can control the logger behavior using environment variables.
We are repeating the same code in every function in libsyclinterface. Instead, a better way can be to just catch std::exception and then pass the exception object to the handler function. We can introduce a big switch inside the handler as shown in the following snippet . Doing so will also address Update sycl interface library to use SYCL 2020 exceptions #628.
C++ allows writing code such as throw 1, so technically not all exceptions are std::exception objects. We should evaluate if handling of non-std::exception objects is required (Improve exception handling inside libsyclinterface #351). I seriously doubt SYCL/dpcpp_cpp_rt is going to do any such a thing, but maybe we can add a special handler to catch all non-std::exception objects?
Make it possible to see the exact file, function, and line where the exception was thrown either using BOOST.log or directly by using the __FILE__, __func__, __LINE__ macros.
So we need to create an overloaded error_handler C++ function with signatures:
void error_handler(
const std::exception &e,
const char *file_name,
const char *func_name,
int line_num,
int level = 0 /* or an enum */
);
void error_handler(
const std::string &what,
const char *file_name,
const char *func_name,
int line_num,
int level = 0 /* or an enum */
);
The former signature would be used from within catch(const std::exception &e) { /* code */ } block, while the latter one can be used for other occasions, e.g. input reference was null, or we are in catch(...) { /* code */ } block.
The error handling should look like
try {
do_something();
} catch(const std::exception &e) {
do_resource_cleanup(); // this may need to be done differently for different e.category() and e.code() valueserror_handler(e, __FILE__, __func__, __LINE__);
} catch(...) {
error_handler(fatal_exeception_string, __FILE__, __func__, __LINE__, FATAL_ERROR_LEVEL);
std::terminate();
}
diptorupd
changed the title
Improving exception handling and logging in libsyclinterface
Improving exception handling and logging in libsyclinterfaceJan 8, 2022
Related #35 #628 #351
The issue relates to an overhaul of the exception handling design in the
libsyclinterface
helper library.Background
libsyclinterface
tries to follow the so-called Abrahams Guarantees design for exception handling. Our intent is to ensure:libsyclinterface
, i.e., all exceptions should be caught.catch
block. (Note: Klockwork is able to catch these issues.)Requirements
Ensure proper exception safety is implemented in
libsyclinterface
by auditing the code and adding negative test cases.Make the handling of exceptions more informative and user configurable.
Currently,
libsyclinterface
only prints out the exception message inside a catch block. The behavior is very rudimentary and not configurable at all. Instead, we can introduce ahandler
function that can log exceptions in different ways, such as print out messages with different levels of verbosity or even write them to a file. The handler function should be added to thehelper
directory.We can use a library such as Boost Log for this purpose. Boost logs allows creating a global logger that I believe is thread safe. Most probably we can control the logger behavior using environment variables.
We are repeating the same code in every function in
libsyclinterface
. Instead, a better way can be to just catchstd::exception
and then pass the exception object to the handler function. We can introduce a big switch inside the handler as shown in the following snippet . Doing so will also address Update sycl interface library to use SYCL 2020 exceptions #628.throw 1
, so technically not all exceptions arestd::exception
objects. We should evaluate if handling of non-std::exception
objects is required (Improve exception handling insidelibsyclinterface
#351). I seriously doubt SYCL/dpcpp_cpp_rt is going to do any such a thing, but maybe we can add a special handler to catch all non-std::exception
objects?BOOST.log
or directly by using the__FILE__
,__func__
,__LINE__
macros.Subtasks:
std::cerr
output #679The text was updated successfully, but these errors were encountered: