Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
G
glog
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
glog
Commits
d1f49ba5
Commit
d1f49ba5
authored
Jun 27, 2017
by
Andrew Schwartzmeyer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support signal handler on Windows
parent
7f95ecfd
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
55 additions
and
18 deletions
+55
-18
CMakeLists.txt
CMakeLists.txt
+2
-2
logging.cc
src/logging.cc
+3
-6
signalhandler.cc
src/signalhandler.cc
+35
-7
signalhandler_unittest.cc
src/signalhandler_unittest.cc
+11
-1
utilities.cc
src/utilities.cc
+4
-2
No files found.
CMakeLists.txt
View file @
d1f49ba5
...
...
@@ -364,9 +364,9 @@ set (GLOG_SRCS
src/vlog_is_on.cc
)
if (HAVE_PTHREAD)
if (HAVE_PTHREAD
OR WIN32
)
list (APPEND GLOG_SRCS src/signalhandler.cc)
endif (HAVE_PTHREAD)
endif (HAVE_PTHREAD
OR WIN32
)
if (WIN32)
list (APPEND GLOG_SRCS
...
...
src/logging.cc
View file @
d1f49ba5
...
...
@@ -1463,16 +1463,13 @@ void LogMessage::RecordCrashReason(
# define ATTRIBUTE_NORETURN
#endif
#if defined(OS_WINDOWS)
__declspec
(
noreturn
)
#endif
static
void
logging_fail
()
ATTRIBUTE_NORETURN
;
static
void
logging_fail
()
{
#if defined(_DEBUG) && defined(_MSC_VER)
// When debugging on windows, avoid the obnoxious dialog and make
// it possible to continue past a LOG(FATAL) in the debugger
__debugbreak
();
#else
abort
();
#endif
}
typedef
void
(
*
logging_fail_func_t
)()
ATTRIBUTE_NORETURN
;
...
...
src/signalhandler.cc
View file @
d1f49ba5
...
...
@@ -48,9 +48,6 @@
_START_GOOGLE_NAMESPACE_
// TOOD(hamaji): Use signal instead of sigaction?
#ifdef HAVE_SIGACTION
namespace
{
// We'll install the failure signal handler for these signals. We could
...
...
@@ -66,10 +63,14 @@ const struct {
{
SIGILL
,
"SIGILL"
},
{
SIGFPE
,
"SIGFPE"
},
{
SIGABRT
,
"SIGABRT"
},
#if !defined(OS_WINDOWS)
{
SIGBUS
,
"SIGBUS"
},
#endif
{
SIGTERM
,
"SIGTERM"
},
};
static
bool
kFailureSignalHandlerInstalled
=
false
;
// Returns the program counter from signal context, NULL if unknown.
void
*
GetPC
(
void
*
ucontext_in_void
)
{
#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
...
...
@@ -168,6 +169,9 @@ void DumpTimeInfo() {
g_failure_writer
(
buf
,
formatter
.
num_bytes_written
());
}
// TOOD(hamaji): Use signal instead of sigaction?
#ifdef HAVE_SIGACTION
// Dumps information about the signal to STDERR.
void
DumpSignalInfo
(
int
signal_number
,
siginfo_t
*
siginfo
)
{
// Get the signal name.
...
...
@@ -213,6 +217,8 @@ void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
g_failure_writer
(
buf
,
formatter
.
num_bytes_written
());
}
#endif // HAVE_SIGACTION
// Dumps information about the stack frame to STDERR.
void
DumpStackFrameInfo
(
const
char
*
prefix
,
void
*
pc
)
{
// Get the symbol name.
...
...
@@ -240,12 +246,17 @@ void DumpStackFrameInfo(const char* prefix, void* pc) {
// Invoke the default signal handler.
void
InvokeDefaultSignalHandler
(
int
signal_number
)
{
#ifdef HAVE_SIGACTION
struct
sigaction
sig_action
;
memset
(
&
sig_action
,
0
,
sizeof
(
sig_action
));
sigemptyset
(
&
sig_action
.
sa_mask
);
sig_action
.
sa_handler
=
SIG_DFL
;
sigaction
(
signal_number
,
&
sig_action
,
NULL
);
kill
(
getpid
(),
signal_number
);
#elif defined(OS_WINDOWS)
signal
(
signal_number
,
SIG_DFL
);
raise
(
signal_number
);
#endif
}
// This variable is used for protecting FailureSignalHandler() from
...
...
@@ -256,9 +267,14 @@ static pthread_t* g_entered_thread_id_pointer = NULL;
// Dumps signal and stack frame information, and invokes the default
// signal handler once our job is done.
#if defined(OS_WINDOWS)
void
FailureSignalHandler
(
int
signal_number
)
#else
void
FailureSignalHandler
(
int
signal_number
,
siginfo_t
*
signal_info
,
void
*
ucontext
)
{
void
*
ucontext
)
#endif
{
// First check if we've already entered the function. We use an atomic
// compare and swap operation for platforms that support it. For other
// platforms, we use a naive method that could lead to a subtle race.
...
...
@@ -298,16 +314,20 @@ void FailureSignalHandler(int signal_number,
// First dump time info.
DumpTimeInfo
();
#if !defined(OS_WINDOWS)
// Get the program counter from ucontext.
void
*
pc
=
GetPC
(
ucontext
);
DumpStackFrameInfo
(
"PC: "
,
pc
);
#endif
#ifdef HAVE_STACKTRACE
// Get the stack traces.
void
*
stack
[
32
];
// +1 to exclude this function.
const
int
depth
=
GetStackTrace
(
stack
,
ARRAYSIZE
(
stack
),
1
);
# ifdef HAVE_SIGACTION
DumpSignalInfo
(
signal_number
,
signal_info
);
# endif
// Dump the stack traces.
for
(
int
i
=
0
;
i
<
depth
;
++
i
)
{
DumpStackFrameInfo
(
" "
,
stack
[
i
]);
...
...
@@ -333,18 +353,19 @@ void FailureSignalHandler(int signal_number,
}
// namespace
#endif // HAVE_SIGACTION
namespace
glog_internal_namespace_
{
bool
IsFailureSignalHandlerInstalled
()
{
#ifdef HAVE_SIGACTION
// TODO(andschwa): Return kFailureSignalHandlerInstalled?
struct
sigaction
sig_action
;
memset
(
&
sig_action
,
0
,
sizeof
(
sig_action
));
sigemptyset
(
&
sig_action
.
sa_mask
);
sigaction
(
SIGABRT
,
NULL
,
&
sig_action
);
if
(
sig_action
.
sa_sigaction
==
&
FailureSignalHandler
)
return
true
;
#elif defined(OS_WINDOWS)
return
kFailureSignalHandlerInstalled
;
#endif // HAVE_SIGACTION
return
false
;
}
...
...
@@ -363,11 +384,18 @@ void InstallFailureSignalHandler() {
for
(
size_t
i
=
0
;
i
<
ARRAYSIZE
(
kFailureSignals
);
++
i
)
{
CHECK_ERR
(
sigaction
(
kFailureSignals
[
i
].
number
,
&
sig_action
,
NULL
));
}
kFailureSignalHandlerInstalled
=
true
;
#elif defined(OS_WINDOWS)
for
(
size_t
i
=
0
;
i
<
ARRAYSIZE
(
kFailureSignals
);
++
i
)
{
CHECK_NE
(
signal
(
kFailureSignals
[
i
].
number
,
&
FailureSignalHandler
),
SIG_ERR
);
}
kFailureSignalHandlerInstalled
=
true
;
#endif // HAVE_SIGACTION
}
void
InstallFailureWriter
(
void
(
*
writer
)(
const
char
*
data
,
int
size
))
{
#if
def HAVE_SIGACTION
#if
defined(HAVE_SIGACTION) || defined(OS_WINDOWS)
g_failure_writer
=
writer
;
#endif // HAVE_SIGACTION
}
...
...
src/signalhandler_unittest.cc
View file @
d1f49ba5
...
...
@@ -34,7 +34,9 @@
#include "utilities.h"
#include <pthread.h>
#if defined(HAVE_PTHREAD)
# include <pthread.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
...
...
@@ -87,12 +89,20 @@ int main(int argc, char **argv) {
fprintf
(
stderr
,
"looping
\n
"
);
while
(
true
);
}
else
if
(
command
==
"die_in_thread"
)
{
#if defined(HAVE_PTHREAD)
pthread_t
thread
;
pthread_create
(
&
thread
,
NULL
,
&
DieInThread
,
NULL
);
pthread_join
(
thread
,
NULL
);
#else
fprintf
(
stderr
,
"no pthread
\n
"
);
return
1
;
#endif
}
else
if
(
command
==
"dump_to_stdout"
)
{
InstallFailureWriter
(
WriteToStdout
);
abort
();
}
else
if
(
command
==
"installed"
)
{
fprintf
(
stderr
,
"signal handler installed: %s
\n
"
,
IsFailureSignalHandlerInstalled
()
?
"true"
:
"false"
);
}
else
{
// Tell the shell script
puts
(
"OK"
);
...
...
src/utilities.cc
View file @
d1f49ba5
...
...
@@ -137,17 +137,19 @@ static void DumpStackTraceAndExit() {
DumpStackTrace
(
1
,
DebugWriteToStderr
,
NULL
);
// TOOD(hamaji): Use signal instead of sigaction?
#ifdef HAVE_SIGACTION
if
(
IsFailureSignalHandlerInstalled
())
{
// Set the default signal handler for SIGABRT, to avoid invoking our
// own signal handler installed by InstallFailureSignalHandler().
#ifdef HAVE_SIGACTION
struct
sigaction
sig_action
;
memset
(
&
sig_action
,
0
,
sizeof
(
sig_action
));
sigemptyset
(
&
sig_action
.
sa_mask
);
sig_action
.
sa_handler
=
SIG_DFL
;
sigaction
(
SIGABRT
,
&
sig_action
,
NULL
);
}
#elif defined(OS_WINDOWS)
signal
(
SIGABRT
,
SIG_DFL
);
#endif // HAVE_SIGACTION
}
abort
();
}
...
...
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