Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
89aebb65
Commit
89aebb65
authored
Feb 21, 2008
by
vvaintroub@wva
Browse files
Options
Browse Files
Download
Plain Diff
Merge vvaintroub@bk-internal.mysql.com:/home/bk/mysql-5.0-build
into wva.:C:/bk/bug31745_2/mysql-5.0-build
parents
71faa393
f5932c0d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
469 additions
and
75 deletions
+469
-75
sql/CMakeLists.txt
sql/CMakeLists.txt
+1
-1
sql/mysqld.cc
sql/mysqld.cc
+178
-47
sql/sql_parse.cc
sql/sql_parse.cc
+2
-17
sql/stacktrace.c
sql/stacktrace.c
+270
-5
sql/stacktrace.h
sql/stacktrace.h
+18
-5
No files found.
sql/CMakeLists.txt
View file @
89aebb65
...
@@ -48,7 +48,7 @@ ENDIF(DISABLE_GRANT_OPTIONS)
...
@@ -48,7 +48,7 @@ ENDIF(DISABLE_GRANT_OPTIONS)
ADD_EXECUTABLE
(
mysqld
${
MYSQLD_EXE_SUFFIX
}
ADD_EXECUTABLE
(
mysqld
${
MYSQLD_EXE_SUFFIX
}
../sql-common/client.c derror.cc des_key_file.cc
../sql-common/client.c derror.cc des_key_file.cc
discover.cc ../libmysql/errmsg.c field.cc field_conv.cc
discover.cc ../libmysql/errmsg.c field.cc
stacktrace.c stacktrace.h
field_conv.cc
filesort.cc gstream.cc ha_blackhole.cc
filesort.cc gstream.cc ha_blackhole.cc
ha_archive.cc ha_heap.cc ha_myisam.cc ha_myisammrg.cc
ha_archive.cc ha_heap.cc ha_myisam.cc ha_myisammrg.cc
ha_innodb.cc ha_federated.cc ha_berkeley.cc
ha_innodb.cc ha_federated.cc ha_berkeley.cc
...
...
sql/mysqld.cc
View file @
89aebb65
...
@@ -138,6 +138,13 @@ extern "C" { // Because of SCO 3.2V4.2
...
@@ -138,6 +138,13 @@ extern "C" { // Because of SCO 3.2V4.2
#include <sys/mman.h>
#include <sys/mman.h>
#endif
#endif
#ifdef __WIN__
#include <crtdbg.h>
#define SIGNAL_FMT "exception 0x%x"
#else
#define SIGNAL_FMT "signal %d"
#endif
#ifdef __NETWARE__
#ifdef __NETWARE__
#define zVOLSTATE_ACTIVE 6
#define zVOLSTATE_ACTIVE 6
#define zVOLSTATE_DEACTIVE 2
#define zVOLSTATE_DEACTIVE 2
...
@@ -227,6 +234,7 @@ inline void set_proper_floating_point_mode()
...
@@ -227,6 +234,7 @@ inline void set_proper_floating_point_mode()
extern
"C"
int
gethostname
(
char
*
name
,
int
namelen
);
extern
"C"
int
gethostname
(
char
*
name
,
int
namelen
);
#endif
#endif
extern
"C"
sig_handler
handle_segfault
(
int
sig
);
/* Constants */
/* Constants */
...
@@ -1031,9 +1039,6 @@ static void __cdecl kill_server(int sig_ptr)
...
@@ -1031,9 +1039,6 @@ static void __cdecl kill_server(int sig_ptr)
#endif
#endif
close_connections
();
close_connections
();
if
(
sig
!=
MYSQL_KILL_SIGNAL
&&
if
(
sig
!=
MYSQL_KILL_SIGNAL
&&
#ifdef __WIN__
sig
!=
SIGINT
&&
/* Bug#18235 */
#endif
sig
!=
0
)
sig
!=
0
)
unireg_abort
(
1
);
/* purecov: inspected */
unireg_abort
(
1
);
/* purecov: inspected */
else
else
...
@@ -1592,8 +1597,7 @@ static void network_init(void)
...
@@ -1592,8 +1597,7 @@ static void network_init(void)
FORMAT_MESSAGE_FROM_SYSTEM
,
FORMAT_MESSAGE_FROM_SYSTEM
,
NULL
,
error
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
NULL
,
error
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
(
LPTSTR
)
&
lpMsgBuf
,
0
,
NULL
);
(
LPTSTR
)
&
lpMsgBuf
,
0
,
NULL
);
MessageBox
(
NULL
,
(
LPTSTR
)
lpMsgBuf
,
"Error from CreateNamedPipe"
,
sql_perror
((
char
*
)
lpMsgBuf
);
MB_OK
|
MB_ICONINFORMATION
);
LocalFree
(
lpMsgBuf
);
LocalFree
(
lpMsgBuf
);
unireg_abort
(
1
);
unireg_abort
(
1
);
}
}
...
@@ -1796,17 +1800,163 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
...
@@ -1796,17 +1800,163 @@ extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
******************************************************************************/
******************************************************************************/
#if defined(__WIN__) || defined(OS2)
#if defined(__WIN__)
/*
On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
with graceful shutdown.
Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
provides possibility to pass the exception to just-in-time debugger, collect
dumps and potentially also the exception and thread context used to output
callstack.
*/
static
BOOL
WINAPI
console_event_handler
(
DWORD
type
)
{
DBUG_ENTER
(
"console_event_handler"
);
if
(
type
==
CTRL_C_EVENT
)
{
/*
Do not shutdown before startup is finished and shutdown
thread is initialized. Otherwise there is a race condition
between main thread doing initialization and CTRL-C thread doing
cleanup, which can result into crash.
*/
if
(
hEventShutdown
)
kill_mysql
();
else
sql_print_warning
(
"CTRL-C ignored during startup"
);
DBUG_RETURN
(
TRUE
);
}
DBUG_RETURN
(
FALSE
);
}
/*
In Visual Studio 2005 and later, default SIGABRT handler will overwrite
any unhandled exception filter set by the application and will try to
call JIT debugger. This is not what we want, this we calling __debugbreak
to stop in debugger, if process is being debugged or to generate
EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
*/
#if (_MSC_VER >= 1400)
static
void
my_sigabrt_handler
(
int
sig
)
{
__debugbreak
();
}
#endif
/*_MSC_VER >=1400 */
void
win_install_sigabrt_handler
(
void
)
{
#if (_MSC_VER >=1400)
/*abort() should not override our exception filter*/
_set_abort_behavior
(
0
,
_CALL_REPORTFAULT
);
signal
(
SIGABRT
,
my_sigabrt_handler
);
#endif
/* _MSC_VER >=1400 */
}
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
#define DEBUGGER_ATTACH_TIMEOUT 120
/*
Wait for debugger to attach and break into debugger. If debugger is not attached,
resume after timeout.
*/
static
void
wait_for_debugger
(
int
timeout_sec
)
{
if
(
!
IsDebuggerPresent
())
{
int
i
;
printf
(
"Waiting for debugger to attach, pid=%u
\n
"
,
GetCurrentProcessId
());
fflush
(
stdout
);
for
(
i
=
0
;
i
<
timeout_sec
;
i
++
)
{
Sleep
(
1000
);
if
(
IsDebuggerPresent
())
{
/* Break into debugger */
__debugbreak
();
return
;
}
}
printf
(
"pid=%u, debugger not attached after %d seconds, resuming
\n
"
,
GetCurrentProcessId
(),
timeout_sec
);
fflush
(
stdout
);
}
}
#endif
/* DEBUG_UNHANDLED_EXCEPTION_FILTER */
LONG
WINAPI
my_unhandler_exception_filter
(
EXCEPTION_POINTERS
*
ex_pointers
)
{
static
BOOL
first_time
=
TRUE
;
if
(
!
first_time
)
{
/*
This routine can be called twice, typically
when detaching in JIT debugger.
Return EXCEPTION_EXECUTE_HANDLER to terminate process.
*/
return
EXCEPTION_EXECUTE_HANDLER
;
}
first_time
=
FALSE
;
#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
/*
Unfortunately there is no clean way to debug unhandled exception filters,
as debugger does not stop there(also documented in MSDN)
To overcome, one could put a MessageBox, but this will not work in service.
Better solution is to print error message and sleep some minutes
until debugger is attached
*/
wait_for_debugger
(
DEBUGGER_ATTACH_TIMEOUT
);
#endif
/* DEBUG_UNHANDLED_EXCEPTION_FILTER */
__try
{
set_exception_pointers
(
ex_pointers
);
handle_segfault
(
ex_pointers
->
ExceptionRecord
->
ExceptionCode
);
}
__except
(
EXCEPTION_EXECUTE_HANDLER
)
{
DWORD
written
;
const
char
msg
[]
=
"Got exception in exception handler!
\n
"
;
WriteFile
(
GetStdHandle
(
STD_OUTPUT_HANDLE
),
msg
,
sizeof
(
msg
)
-
1
,
&
written
,
NULL
);
}
/*
Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
(drwtsn32 or vsjitdebugger) possibility to attach,
if JIT debugger is configured.
Windows Error reporting might generate a dump here.
*/
return
EXCEPTION_CONTINUE_SEARCH
;
}
static
void
init_signals
(
void
)
static
void
init_signals
(
void
)
{
{
int
signals
[]
=
{
SIGINT
,
SIGILL
,
SIGFPE
,
SIGSEGV
,
SIGTERM
,
SIGABRT
}
;
win_install_sigabrt_handler
();
for
(
uint
i
=
0
;
i
<
sizeof
(
signals
)
/
sizeof
(
int
)
;
i
++
)
if
(
opt_console
)
signal
(
signals
[
i
],
kill_server
)
;
SetConsoleCtrlHandler
(
console_event_handler
,
TRUE
);
#if defined(__WIN__)
else
signal
(
SIGBREAK
,
SIG_IGN
);
//ignore SIGBREAK for NT
{
#else
/* Avoid MessageBox()es*/
signal
(
SIGBREAK
,
kill_server
);
_CrtSetReportMode
(
_CRT_WARN
,
_CRTDBG_MODE_FILE
);
#endif
_CrtSetReportFile
(
_CRT_WARN
,
_CRTDBG_FILE_STDERR
);
_CrtSetReportMode
(
_CRT_ERROR
,
_CRTDBG_MODE_FILE
);
_CrtSetReportFile
(
_CRT_ERROR
,
_CRTDBG_FILE_STDERR
);
_CrtSetReportMode
(
_CRT_ASSERT
,
_CRTDBG_MODE_FILE
);
_CrtSetReportFile
(
_CRT_ASSERT
,
_CRTDBG_FILE_STDERR
);
/*
Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
because it would prevent JIT debugger and Windows error reporting
from working. We need WER or JIT-debugging, since our own unhandled
exception filter is not guaranteed to work in all situation
(like heap corruption or stack overflow)
*/
SetErrorMode
(
SetErrorMode
(
0
)
|
SEM_FAILCRITICALERRORS
|
SEM_NOOPENFILEERRORBOX
);
}
SetUnhandledExceptionFilter
(
my_unhandler_exception_filter
);
}
}
static
void
start_signal_handler
(
void
)
static
void
start_signal_handler
(
void
)
...
@@ -2094,8 +2244,8 @@ static void start_signal_handler(void)
...
@@ -2094,8 +2244,8 @@ static void start_signal_handler(void)
static
void
check_data_home
(
const
char
*
path
)
static
void
check_data_home
(
const
char
*
path
)
{}
{}
#endif
/*__WIN__ || __NETWARE || __EMX__*/
#else
/* if ! __WIN__ && ! __EMX__ */
#ifdef HAVE_LINUXTHREADS
#ifdef HAVE_LINUXTHREADS
#define UNSAFE_DEFAULT_LINUX_THREADS 200
#define UNSAFE_DEFAULT_LINUX_THREADS 200
...
@@ -2115,7 +2265,7 @@ extern "C" sig_handler handle_segfault(int sig)
...
@@ -2115,7 +2265,7 @@ extern "C" sig_handler handle_segfault(int sig)
*/
*/
if
(
segfaulted
)
if
(
segfaulted
)
{
{
fprintf
(
stderr
,
"Fatal
signal %d
while backtracing
\n
"
,
sig
);
fprintf
(
stderr
,
"Fatal
"
SIGNAL_FMT
"
while backtracing
\n
"
,
sig
);
exit
(
1
);
exit
(
1
);
}
}
...
@@ -2125,7 +2275,7 @@ extern "C" sig_handler handle_segfault(int sig)
...
@@ -2125,7 +2275,7 @@ extern "C" sig_handler handle_segfault(int sig)
localtime_r
(
&
curr_time
,
&
tm
);
localtime_r
(
&
curr_time
,
&
tm
);
fprintf
(
stderr
,
"\
fprintf
(
stderr
,
"\
%02d%02d%02d %2d:%02d:%02d - mysqld got
signal %d
;
\n
\
%02d%02d%02d %2d:%02d:%02d - mysqld got
"
SIGNAL_FMT
"
;
\n
\
This could be because you hit a bug. It is also possible that this binary
\n
\
This could be because you hit a bug. It is also possible that this binary
\n
\
or one of the libraries it was linked against is corrupt, improperly built,
\n
\
or one of the libraries it was linked against is corrupt, improperly built,
\n
\
or misconfigured. This error can also be caused by malfunctioning hardware.
\n
"
,
or misconfigured. This error can also be caused by malfunctioning hardware.
\n
"
,
...
@@ -2166,6 +2316,10 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
...
@@ -2166,6 +2316,10 @@ the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
if
(
!
(
test_flags
&
TEST_NO_STACKTRACE
))
if
(
!
(
test_flags
&
TEST_NO_STACKTRACE
))
{
{
fprintf
(
stderr
,
"thd=%p
\n
"
,
thd
);
fprintf
(
stderr
,
"thd=%p
\n
"
,
thd
);
fprintf
(
stderr
,
"\
Attempting backtrace. You can use the following information to find out
\n
\
where mysqld died. If you see no messages after this, something went
\n
\
terribly wrong...
\n
"
);
print_stacktrace
(
thd
?
(
gptr
)
thd
->
thread_stack
:
(
gptr
)
0
,
print_stacktrace
(
thd
?
(
gptr
)
thd
->
thread_stack
:
(
gptr
)
0
,
thread_stack
);
thread_stack
);
}
}
...
@@ -2214,15 +2368,22 @@ of those buggy OS calls. You should consider whether you really need the\n\
...
@@ -2214,15 +2368,22 @@ of those buggy OS calls. You should consider whether you really need the\n\
bugs.
\n
"
);
bugs.
\n
"
);
}
}
#ifdef HAVE_WRITE_CORE
if
(
test_flags
&
TEST_CORE_ON_SIGNAL
)
if
(
test_flags
&
TEST_CORE_ON_SIGNAL
)
{
{
fprintf
(
stderr
,
"Writing a core file
\n
"
);
fprintf
(
stderr
,
"Writing a core file
\n
"
);
fflush
(
stderr
);
fflush
(
stderr
);
write_core
(
sig
);
write_core
(
sig
);
}
}
#endif
#ifndef __WIN__
/* On Windows, do not terminate, but pass control to exception filter */
exit
(
1
);
exit
(
1
);
#endif
}
}
#if !defined(__WIN__) && !defined(__NETWARE__) && !defined(__EMX__)
#ifndef SA_RESETHAND
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
#define SA_RESETHAND 0
#endif
#endif
...
@@ -2567,19 +2728,6 @@ static void my_str_free_mysqld(void *ptr)
...
@@ -2567,19 +2728,6 @@ static void my_str_free_mysqld(void *ptr)
#ifdef __WIN__
#ifdef __WIN__
struct
utsname
{
char
nodename
[
FN_REFLEN
];
};
int
uname
(
struct
utsname
*
a
)
{
return
-
1
;
}
pthread_handler_t
handle_shutdown
(
void
*
arg
)
pthread_handler_t
handle_shutdown
(
void
*
arg
)
{
{
MSG
msg
;
MSG
msg
;
...
@@ -2593,18 +2741,6 @@ pthread_handler_t handle_shutdown(void *arg)
...
@@ -2593,18 +2741,6 @@ pthread_handler_t handle_shutdown(void *arg)
kill_server
(
MYSQL_KILL_SIGNAL
);
kill_server
(
MYSQL_KILL_SIGNAL
);
return
0
;
return
0
;
}
}
int
STDCALL
handle_kill
(
ulong
ctrl_type
)
{
if
(
ctrl_type
==
CTRL_CLOSE_EVENT
||
ctrl_type
==
CTRL_SHUTDOWN_EVENT
)
{
kill_server
(
MYSQL_KILL_SIGNAL
);
return
TRUE
;
}
return
FALSE
;
}
#endif
#endif
...
@@ -3633,11 +3769,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
...
@@ -3633,11 +3769,6 @@ we force server id to 2, but this MySQL server will not act as a slave.");
freopen
(
log_error_file
,
"a+"
,
stderr
);
freopen
(
log_error_file
,
"a+"
,
stderr
);
FreeConsole
();
// Remove window
FreeConsole
();
// Remove window
}
}
else
{
/* Don't show error dialog box when on foreground: it stops the server */
SetErrorMode
(
SEM_NOOPENFILEERRORBOX
|
SEM_FAILCRITICALERRORS
);
}
#endif
#endif
/*
/*
...
...
sql/sql_parse.cc
View file @
89aebb65
...
@@ -98,22 +98,7 @@ static bool do_command(THD *thd);
...
@@ -98,22 +98,7 @@ static bool do_command(THD *thd);
#endif // EMBEDDED_LIBRARY
#endif // EMBEDDED_LIBRARY
#ifdef __WIN__
#ifdef __WIN__
static
void
test_signal
(
int
sig_ptr
)
extern
void
win_install_sigabrt_handler
(
void
);
{
#if !defined( DBUG_OFF)
MessageBox
(
NULL
,
"Test signal"
,
"DBUG"
,
MB_OK
);
#endif
#if defined(OS2)
fprintf
(
stderr
,
"Test signal %d
\n
"
,
sig_ptr
);
fflush
(
stderr
);
#endif
}
static
void
init_signals
(
void
)
{
int
signals
[
7
]
=
{
SIGINT
,
SIGILL
,
SIGFPE
,
SIGSEGV
,
SIGTERM
,
SIGBREAK
,
SIGABRT
}
;
for
(
int
i
=
0
;
i
<
7
;
i
++
)
signal
(
signals
[
i
],
test_signal
)
;
}
#endif
#endif
static
void
unlock_locked_tables
(
THD
*
thd
)
static
void
unlock_locked_tables
(
THD
*
thd
)
...
@@ -1124,7 +1109,7 @@ pthread_handler_t handle_one_connection(void *arg)
...
@@ -1124,7 +1109,7 @@ pthread_handler_t handle_one_connection(void *arg)
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
/* now that we've called my_thread_init(), it is safe to call DBUG_* */
#if defined(__WIN__)
#if defined(__WIN__)
init_signals
();
win_install_sigabrt_handler
();
#elif !defined(OS2) && !defined(__NETWARE__)
#elif !defined(OS2) && !defined(__NETWARE__)
sigset_t
set
;
sigset_t
set
;
VOID
(
sigemptyset
(
&
set
));
// Get mask in use
VOID
(
sigemptyset
(
&
set
));
// Get mask in use
...
...
sql/stacktrace.c
View file @
89aebb65
...
@@ -13,11 +13,15 @@
...
@@ -13,11 +13,15 @@
along with this program; if not, write to the Free Software
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Workaround for Bug#32082: VOID redefinition on Win results in compile errors*/
#define DONT_DEFINE_VOID 1
#include <my_global.h>
#include <my_global.h>
#include "stacktrace.h"
#include "stacktrace.h"
#ifndef __WIN__
#include <signal.h>
#include <signal.h>
#include <my_pthread.h>
#include <my_pthread.h>
#ifdef HAVE_STACKTRACE
#ifdef HAVE_STACKTRACE
#include <unistd.h>
#include <unistd.h>
#include <strings.h>
#include <strings.h>
...
@@ -118,10 +122,7 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
...
@@ -118,10 +122,7 @@ void print_stacktrace(gptr stack_bottom, ulong thread_stack)
#endif
#endif
LINT_INIT
(
fp
);
LINT_INIT
(
fp
);
fprintf
(
stderr
,
"\
Attempting backtrace. You can use the following information to find out
\n
\
where mysqld died. If you see no messages after this, something went
\n
\
terribly wrong...
\n
"
);
#ifdef __i386__
#ifdef __i386__
__asm
__volatile__
(
"movl %%ebp,%0"
__asm
__volatile__
(
"movl %%ebp,%0"
:
"=r"
(
fp
)
:
"=r"
(
fp
)
...
@@ -257,3 +258,267 @@ void write_core(int sig)
...
@@ -257,3 +258,267 @@ void write_core(int sig)
#endif
#endif
}
}
#endif
#endif
#else
/* __WIN__*/
#include <dbghelp.h>
/*
Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
We do not redistribute dbghelp and the one comes with older OS (up to Windows 2000)
is missing some important functions like functions StackWalk64 or MinidumpWriteDump.
Hence, we have to load functions at runtime using LoadLibrary/GetProcAddress.
*/
typedef
DWORD
(
WINAPI
*
SymSetOptions_FctType
)(
DWORD
dwOptions
);
typedef
BOOL
(
WINAPI
*
SymGetModuleInfo64_FctType
)
(
HANDLE
,
DWORD64
,
PIMAGEHLP_MODULE64
)
;
typedef
BOOL
(
WINAPI
*
SymGetSymFromAddr64_FctType
)
(
HANDLE
,
DWORD64
,
PDWORD64
,
PIMAGEHLP_SYMBOL64
)
;
typedef
BOOL
(
WINAPI
*
SymGetLineFromAddr64_FctType
)
(
HANDLE
,
DWORD64
,
PDWORD
,
PIMAGEHLP_LINE64
);
typedef
BOOL
(
WINAPI
*
SymInitialize_FctType
)
(
HANDLE
,
PSTR
,
BOOL
);
typedef
BOOL
(
WINAPI
*
StackWalk64_FctType
)
(
DWORD
,
HANDLE
,
HANDLE
,
LPSTACKFRAME64
,
PVOID
,
PREAD_PROCESS_MEMORY_ROUTINE64
,
PFUNCTION_TABLE_ACCESS_ROUTINE64
,
PGET_MODULE_BASE_ROUTINE64
,
PTRANSLATE_ADDRESS_ROUTINE64
);
typedef
BOOL
(
WINAPI
*
MiniDumpWriteDump_FctType
)(
IN
HANDLE
hProcess
,
IN
DWORD
ProcessId
,
IN
HANDLE
hFile
,
IN
MINIDUMP_TYPE
DumpType
,
IN
CONST
PMINIDUMP_EXCEPTION_INFORMATION
ExceptionParam
,
OPTIONAL
IN
CONST
PMINIDUMP_USER_STREAM_INFORMATION
UserStreamParam
,
OPTIONAL
IN
CONST
PMINIDUMP_CALLBACK_INFORMATION
CallbackParam
OPTIONAL
);
static
SymSetOptions_FctType
pSymSetOptions
;
static
SymGetModuleInfo64_FctType
pSymGetModuleInfo64
;
static
SymGetSymFromAddr64_FctType
pSymGetSymFromAddr64
;
static
SymInitialize_FctType
pSymInitialize
;
static
StackWalk64_FctType
pStackWalk64
;
static
SymGetLineFromAddr64_FctType
pSymGetLineFromAddr64
;
static
MiniDumpWriteDump_FctType
pMiniDumpWriteDump
;
static
EXCEPTION_POINTERS
*
exception_ptrs
;
#define MODULE64_SIZE_WINXP 576
#define STACKWALK_MAX_FRAMES 64
/*
Dynamically load dbghelp functions
*/
BOOL
init_dbghelp_functions
()
{
static
BOOL
first_time
=
TRUE
;
static
BOOL
rc
;
HMODULE
hDbghlp
;
if
(
first_time
)
{
first_time
=
FALSE
;
hDbghlp
=
LoadLibrary
(
"dbghelp"
);
if
(
!
hDbghlp
)
{
rc
=
FALSE
;
return
rc
;
}
pSymSetOptions
=
(
SymSetOptions_FctType
)
GetProcAddress
(
hDbghlp
,
"SymSetOptions"
);
pSymInitialize
=
(
SymInitialize_FctType
)
GetProcAddress
(
hDbghlp
,
"SymInitialize"
);
pSymGetModuleInfo64
=
(
SymGetModuleInfo64_FctType
)
GetProcAddress
(
hDbghlp
,
"SymGetModuleInfo64"
);
pSymGetLineFromAddr64
=
(
SymGetLineFromAddr64_FctType
)
GetProcAddress
(
hDbghlp
,
"SymGetLineFromAddr64"
);
pSymGetSymFromAddr64
=
(
SymGetSymFromAddr64_FctType
)
GetProcAddress
(
hDbghlp
,
"SymGetSymFromAddr64"
);
pStackWalk64
=
(
StackWalk64_FctType
)
GetProcAddress
(
hDbghlp
,
"StackWalk64"
);
pMiniDumpWriteDump
=
(
MiniDumpWriteDump_FctType
)
GetProcAddress
(
hDbghlp
,
"MiniDumpWriteDump"
);
rc
=
(
BOOL
)(
pSymSetOptions
&&
pSymInitialize
&&
pSymGetModuleInfo64
&&
pSymGetLineFromAddr64
&&
pSymGetSymFromAddr64
&&
pStackWalk64
);
}
return
rc
;
}
void
set_exception_pointers
(
EXCEPTION_POINTERS
*
ep
)
{
exception_ptrs
=
ep
;
}
/* Platform SDK in VS2003 does not have definition for SYMOPT_NO_PROMPTS*/
#ifndef SYMOPT_NO_PROMPTS
#define SYMOPT_NO_PROMPTS 0
#endif
void
print_stacktrace
(
gptr
unused1
,
ulong
unused2
)
{
HANDLE
hProcess
=
GetCurrentProcess
();
HANDLE
hThread
=
GetCurrentThread
();
static
IMAGEHLP_MODULE64
module
=
{
sizeof
(
module
)};
static
IMAGEHLP_SYMBOL64_PACKAGE
package
;
DWORD64
addr
;
DWORD
machine
;
int
i
;
CONTEXT
context
;
STACKFRAME64
frame
=
{
0
};
if
(
!
exception_ptrs
||
!
init_dbghelp_functions
())
return
;
/* Copy context, as stackwalking on original will unwind the stack */
context
=
*
(
exception_ptrs
->
ContextRecord
);
/*Initialize symbols.*/
pSymSetOptions
(
SYMOPT_LOAD_LINES
|
SYMOPT_NO_PROMPTS
|
SYMOPT_DEFERRED_LOADS
|
SYMOPT_DEBUG
);
pSymInitialize
(
hProcess
,
NULL
,
TRUE
);
/*Prepare stackframe for the first StackWalk64 call*/
frame
.
AddrFrame
.
Mode
=
frame
.
AddrPC
.
Mode
=
frame
.
AddrStack
.
Mode
=
AddrModeFlat
;
#if (defined _M_IX86)
machine
=
IMAGE_FILE_MACHINE_I386
;
frame
.
AddrFrame
.
Offset
=
context
.
Ebp
;
frame
.
AddrPC
.
Offset
=
context
.
Eip
;
frame
.
AddrStack
.
Offset
=
context
.
Esp
;
#elif (defined _M_X64)
machine
=
IMAGE_FILE_MACHINE_AMD64
;
frame
.
AddrFrame
.
Offset
=
context
.
Rbp
;
frame
.
AddrPC
.
Offset
=
context
.
Rip
;
frame
.
AddrStack
.
Offset
=
context
.
Rsp
;
#else
/*There is currently no need to support IA64*/
#pragma error ("unsupported architecture")
#endif
package
.
sym
.
SizeOfStruct
=
sizeof
(
package
.
sym
);
package
.
sym
.
MaxNameLength
=
sizeof
(
package
.
name
);
/*Walk the stack, output useful information*/
for
(
i
=
0
;
i
<
STACKWALK_MAX_FRAMES
;
i
++
)
{
DWORD64
function_offset
=
0
;
DWORD
line_offset
=
0
;
IMAGEHLP_LINE64
line
=
{
sizeof
(
line
)};
BOOL
have_module
=
FALSE
;
BOOL
have_symbol
=
FALSE
;
BOOL
have_source
=
FALSE
;
if
(
!
pStackWalk64
(
machine
,
hProcess
,
hThread
,
&
frame
,
&
context
,
0
,
0
,
0
,
0
))
break
;
addr
=
frame
.
AddrPC
.
Offset
;
have_module
=
pSymGetModuleInfo64
(
hProcess
,
addr
,
&
module
);
#ifdef _M_IX86
if
(
!
have_module
)
{
/*
ModuleInfo structure has been "compatibly" extended in releases after XP,
and its size was increased. To make XP dbghelp.dll function
happy, pretend passing the old structure.
*/
module
.
SizeOfStruct
=
MODULE64_SIZE_WINXP
;
have_module
=
pSymGetModuleInfo64
(
hProcess
,
addr
,
&
module
);
}
#endif
have_symbol
=
pSymGetSymFromAddr64
(
hProcess
,
addr
,
&
function_offset
,
&
(
package
.
sym
));
have_source
=
pSymGetLineFromAddr64
(
hProcess
,
addr
,
&
line_offset
,
&
line
);
fprintf
(
stderr
,
"%p "
,
addr
);
if
(
have_module
)
{
char
*
base_image_name
=
strrchr
(
module
.
ImageName
,
'\\'
);
if
(
base_image_name
)
base_image_name
++
;
else
base_image_name
=
module
.
ImageName
;
fprintf
(
stderr
,
"%s!"
,
base_image_name
);
}
if
(
have_symbol
)
fprintf
(
stderr
,
"%s()"
,
package
.
sym
.
Name
);
else
if
(
have_module
)
fprintf
(
stderr
,
"???"
);
if
(
have_source
)
{
char
*
base_file_name
=
strrchr
(
line
.
FileName
,
'\\'
);
if
(
base_file_name
)
base_file_name
++
;
else
base_file_name
=
line
.
FileName
;
fprintf
(
stderr
,
"[%s:%u]"
,
base_file_name
,
line
.
LineNumber
);
}
fprintf
(
stderr
,
"
\n
"
);
}
fflush
(
stderr
);
}
/*
Write dump. The dump is created in current directory,
file name is constructed from executable name plus
".dmp" extension
*/
void
write_core
(
int
unused
)
{
char
path
[
MAX_PATH
];
char
dump_fname
[
MAX_PATH
]
=
"core.dmp"
;
MINIDUMP_EXCEPTION_INFORMATION
info
;
HANDLE
hFile
;
if
(
!
exception_ptrs
||
!
init_dbghelp_functions
()
||
!
pMiniDumpWriteDump
)
return
;
info
.
ExceptionPointers
=
exception_ptrs
;
info
.
ClientPointers
=
FALSE
;
info
.
ThreadId
=
GetCurrentThreadId
();
if
(
GetModuleFileName
(
NULL
,
path
,
sizeof
(
path
)))
{
_splitpath
(
path
,
NULL
,
NULL
,
dump_fname
,
NULL
);
strncat
(
dump_fname
,
".dmp"
,
sizeof
(
dump_fname
));
}
hFile
=
CreateFile
(
dump_fname
,
GENERIC_WRITE
,
0
,
0
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
0
);
if
(
hFile
)
{
/* Create minidump */
if
(
pMiniDumpWriteDump
(
GetCurrentProcess
(),
GetCurrentProcessId
(),
hFile
,
MiniDumpNormal
,
&
info
,
0
,
0
))
{
fprintf
(
stderr
,
"Minidump written to %s
\n
"
,
_fullpath
(
path
,
dump_fname
,
sizeof
(
path
))
?
path
:
dump_fname
);
}
else
{
fprintf
(
stderr
,
"MiniDumpWriteDump() failed, last error %u
\n
"
,
GetLastError
());
}
CloseHandle
(
hFile
);
}
else
{
fprintf
(
stderr
,
"CreateFile(%s) failed, last error %u
\n
"
,
dump_fname
,
GetLastError
());
}
fflush
(
stderr
);
}
void
safe_print_str
(
const
char
*
name
,
const
char
*
val
,
int
len
)
{
fprintf
(
stderr
,
"%s at %p"
,
name
,
val
);
__try
{
fprintf
(
stderr
,
"=%.*s
\n
"
,
len
,
val
);
}
__except
(
EXCEPTION_EXECUTE_HANDLER
)
{
fprintf
(
stderr
,
"is an invalid string pointer
\n
"
);
}
}
#endif
/*__WIN__*/
sql/stacktrace.h
View file @
89aebb65
...
@@ -29,20 +29,33 @@ extern char* heap_start;
...
@@ -29,20 +29,33 @@ extern char* heap_start;
heap_start = (char*) &__bss_start; \
heap_start = (char*) &__bss_start; \
check_thread_lib(); \
check_thread_lib(); \
} while(0);
} while(0);
void
check_thread_lib
(
void
);
#endif
/* defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#elif defined (__WIN__)
#define HAVE_STACKTRACE
extern
void
set_exception_pointers
(
EXCEPTION_POINTERS
*
ep
);
#define init_stacktrace() {}
#endif
#ifdef HAVE_STACKTRACE
void
print_stacktrace
(
gptr
stack_bottom
,
ulong
thread_stack
);
void
print_stacktrace
(
gptr
stack_bottom
,
ulong
thread_stack
);
void
safe_print_str
(
const
char
*
name
,
const
char
*
val
,
int
max_len
);
void
safe_print_str
(
const
char
*
name
,
const
char
*
val
,
int
max_len
);
void
check_thread_lib
(
void
);
#else
#endif
/* (defined (__i386__) || (defined(__alpha__) && defined(__GNUC__))) */
#endif
/* TARGET_OS_LINUX */
/* Define empty prototypes for functions that are not implemented */
/* Define empty prototypes for functions that are not implemented */
#ifndef HAVE_STACKTRACE
#define init_stacktrace() {}
#define init_stacktrace() {}
#define print_stacktrace(A,B) {}
#define print_stacktrace(A,B) {}
#define safe_print_str(A,B,C) {}
#define safe_print_str(A,B,C) {}
#endif
/* HAVE_STACKTRACE */
#endif
/* HAVE_STACKTRACE */
#if !defined(__NETWARE__)
#define HAVE_WRITE_CORE
#endif
#ifdef HAVE_WRITE_CORE
void
write_core
(
int
sig
);
void
write_core
(
int
sig
);
#endif
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
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