Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
236e54d5
Unverified
Commit
236e54d5
authored
Mar 19, 2018
by
Kenton Varda
Committed by
GitHub
Mar 19, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #645 from capnproto/unknown-exception
When catching an unknown exception type, at least log the type.
parents
b0775d6d
f8ccf160
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
85 additions
and
12 deletions
+85
-12
exception-test.c++
c++/src/kj/exception-test.c++
+31
-0
exception.c++
c++/src/kj/exception.c++
+48
-12
exception.h
c++/src/kj/exception.h
+6
-0
No files found.
c++/src/kj/exception-test.c++
View file @
236e54d5
...
...
@@ -22,6 +22,7 @@
#include "exception.h"
#include "debug.h"
#include <kj/compat/gtest.h>
#include <stdexcept>
namespace
kj
{
namespace
_
{
// private
...
...
@@ -56,6 +57,36 @@ TEST(Exception, RunCatchingExceptions) {
}
}
#if !KJ_NO_EXCEPTIONS
TEST
(
Exception
,
RunCatchingExceptionsStdException
)
{
Maybe
<
Exception
>
e
=
kj
::
runCatchingExceptions
([
&
]()
{
throw
std
::
logic_error
(
"foo"
);
});
KJ_IF_MAYBE
(
ex
,
e
)
{
EXPECT_EQ
(
"std::exception: foo"
,
ex
->
getDescription
());
}
else
{
ADD_FAILURE
()
<<
"Expected exception"
;
}
}
TEST
(
Exception
,
RunCatchingExceptionsOtherException
)
{
Maybe
<
Exception
>
e
=
kj
::
runCatchingExceptions
([
&
]()
{
throw
123
;
});
KJ_IF_MAYBE
(
ex
,
e
)
{
#if __GNUC__ && !KJ_NO_RTTI
EXPECT_EQ
(
"unknown non-KJ exception of type: int"
,
ex
->
getDescription
());
#else
EXPECT_EQ
(
"unknown non-KJ exception"
,
ex
->
getDescription
());
#endif
}
else
{
ADD_FAILURE
()
<<
"Expected exception"
;
}
}
#endif
#if !KJ_NO_EXCEPTIONS
// We skip this test when exceptions are disabled because making it no-exceptions-safe defeats
// the purpose of the test: recoverable exceptions won't throw inside a destructor in the first
...
...
c++/src/kj/exception.c++
View file @
236e54d5
...
...
@@ -35,6 +35,13 @@
#endif
#include "io.h"
#if !KJ_NO_RTTI
#include <typeinfo>
#if __GNUC__
#include <cxxabi.h>
#endif
#endif
#if (__linux__ && __GLIBC__ && !__UCLIBC__) || __APPLE__
#define KJ_HAS_BACKTRACE 1
#include <execinfo.h>
...
...
@@ -834,7 +841,13 @@ void throwRecoverableException(kj::Exception&& exception, uint ignoreCount) {
namespace
_
{
// private
#if __GNUC__
#if __cplusplus >= 201703L
uint
uncaughtExceptionCount
()
{
return
std
::
uncaught_exceptions
();
}
#elif __GNUC__
// Horrible -- but working -- hack: We can dig into __cxa_get_globals() in order to extract the
// count of uncaught exceptions. This function is part of the C++ ABI implementation used on Linux,
...
...
@@ -858,17 +871,16 @@ struct FakeEhGlobals {
uint
uncaughtExceptions
;
};
// Because of the 'extern "C"', the symbol name is not mangled and thus the namespace is effectively
// ignored for linking. Thus it doesn't matter that we are declaring __cxa_get_globals() in a
// different namespace from the ABI's definition.
extern
"C"
{
FakeEhGlobals
*
__cxa_get_globals
();
}
// LLVM's libstdc++ doesn't declare __cxa_get_globals in its cxxabi.h. GNU does. Because it is
// extern "C", the compiler wills get upset if we re-declare it even in a different namespace.
#if _LIBCPPABI_VERSION
extern
"C"
void
*
__cxa_get_globals
();
#else
using
abi
::
__cxa_get_globals
;
#endif
uint
uncaughtExceptionCount
()
{
// TODO(perf): Use __cxa_get_globals_fast()? Requires that __cxa_get_globals() has been called
// from somewhere.
return
__cxa_get_globals
()
->
uncaughtExceptions
;
return
reinterpret_cast
<
FakeEhGlobals
*>
(
__cxa_get_globals
())
->
uncaughtExceptions
;
}
#elif _MSC_VER
...
...
@@ -918,6 +930,26 @@ void UnwindDetector::catchExceptionsAsSecondaryFaults(_::Runnable& runnable) con
runCatchingExceptions
(
runnable
);
}
#if __GNUC__ && !KJ_NO_RTTI
static
kj
::
String
demangleTypeName
(
const
char
*
name
)
{
if
(
name
==
nullptr
)
return
kj
::
heapString
(
"(nil)"
);
int
status
;
char
*
buf
=
abi
::
__cxa_demangle
(
name
,
nullptr
,
nullptr
,
&
status
);
kj
::
String
result
=
kj
::
heapString
(
buf
==
nullptr
?
name
:
buf
);
free
(
buf
);
return
kj
::
mv
(
result
);
}
kj
::
String
getCaughtExceptionType
()
{
return
demangleTypeName
(
abi
::
__cxa_current_exception_type
()
->
name
());
}
#else
kj
::
String
getCaughtExceptionType
()
{
return
kj
::
heapString
(
"(unknown)"
);
}
#endif
namespace
_
{
// private
class
RecoverableExceptionCatcher
:
public
ExceptionCallback
{
...
...
@@ -960,8 +992,12 @@ Maybe<Exception> runCatchingExceptions(Runnable& runnable) noexcept {
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"std::exception: "
,
e
.
what
()));
}
catch
(...)
{
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"Unknown non-KJ exception."
));
#if __GNUC__ && !KJ_NO_RTTI
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"unknown non-KJ exception of type: "
,
getCaughtExceptionType
()));
#else
return
Exception
(
Exception
::
Type
::
FAILED
,
"(unknown)"
,
-
1
,
str
(
"unknown non-KJ exception"
));
#endif
}
#endif
}
...
...
c++/src/kj/exception.h
View file @
236e54d5
...
...
@@ -373,4 +373,10 @@ kj::StringPtr trimSourceFilename(kj::StringPtr filename);
// Given a source code file name, trim off noisy prefixes like "src/" or
// "/ekam-provider/canonical/".
kj
::
String
getCaughtExceptionType
();
// Utility function which attempts to return the human-readable type name of the exception
// currently being thrown. This can be called inside a catch block, including a catch (...) block,
// for the purpose of error logging. This function is best-effort; on some platforms it may simply
// return "(unknown)".
}
// namespace kj
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment