mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
16115af97c
Fixed problem with LIKE with latin1_de Added parsing support of UNSIGNED LONG LONG Docs/manual.texi: Changelog client/client_priv.h: Changed to use my_global.h client/completion_hash.cc: Changed to use my_global.h client/errmsg.c: Changed to use my_global.h client/get_password.c: Changed to use my_global.h client/mysqldump.c: Changed to use my_global.h client/mysqlshow.c: Changed to use my_global.h client/mysqltest.c: Changed to use my_global.h client/password.c: Changed to use my_global.h client/readline.cc: Changed to use my_global.h client/sql_string.cc: Changed to use my_global.h client/thimble.cc: Changed to use my_global.h client/thread_test.c: Changed to use my_global.h dbug/dbug.c: Changed to use my_global.h dbug/dbug_analyze.c: Changed to use my_global.h dbug/example1.c: Changed to use my_global.h dbug/example2.c: Changed to use my_global.h dbug/example3.c: Changed to use my_global.h dbug/factorial.c: Changed to use my_global.h dbug/main.c: Changed to use my_global.h dbug/sanity.c: Changed to use my_global.h extra/comp_err.c: Changed to use my_global.h extra/my_print_defaults.c: Changed to use my_global.h extra/perror.c: Changed to use my_global.h extra/replace.c: Changed to use my_global.h extra/resolve_stack_dump.c: Changed to use my_global.h extra/resolveip.c: Changed to use my_global.h fs/libmysqlfs.h: Changed to use my_global.h fs/mysqlcorbafs.h: Changed to use my_global.h heap/hp_test1.c: Changed to use my_global.h include/Makefile.am: Changed to use my_global.h include/m_ctype.h: Changed to use my_global.h include/my_base.h: Changed to use my_global.h innobase/include/univ.i: Changed to use my_global.h libmysql/dll.c: Changed to use my_global.h libmysql/errmsg.c: Changed to use my_global.h libmysql/get_password.c: Changed to use my_global.h libmysql/libmysql.c: Changed to use my_global.h libmysql/net.c: Changed to use my_global.h libmysql/password.c: Changed to use my_global.h libmysqld/lib_sql.cc: Changed to use my_global.h libmysqld/lib_vio.c: Changed to use my_global.h libmysqld/libmysqld.c: Changed to use my_global.h mysql-test/mysql-test-run.sh: Changed to use latin1 as default character set mysql-test/r/ctype_latin1_de.result: Changed to use my_global.h mysql-test/r/func_like.result: New test mysql-test/t/ctype_latin1_de.test: Added test of part keys mysql-test/t/func_like.test: New test mysys/checksum.c: Changed to use my_global.h mysys/getopt.c: Changed to use my_global.h mysys/getopt1.c: Changed to use my_global.h mysys/make-conf.c: Changed to use my_global.h mysys/my_alloc.c: Changed to use my_global.h mysys/my_clock.c: Changed to use my_global.h mysys/my_compress.c: Changed to use my_global.h mysys/mysys_priv.h: Changed to use my_global.h mysys/test_charset.c: Changed to use my_global.h mysys/testhash.c: Changed to use my_global.h mysys/thr_alarm.c: Changed to use my_global.h mysys/thr_mutex.c: Changed to use my_global.h regex/debug.c: Changed to use my_global.h regex/main.c: Changed to use my_global.h regex/regcomp.c: Changed to use my_global.h regex/regerror.c: Changed to use my_global.h regex/regexec.c: Changed to use my_global.h regex/regexp.c: Changed to use my_global.h regex/regfree.c: Changed to use my_global.h regex/reginit.c: Changed to use my_global.h sql/cache_manager.cc: Changed to use my_global.h sql/gen_lex_hash.cc: Changed to use my_global.h sql/ha_berkeley.cc: Fixed problem with UNIQUE keys that could contain NULL sql/ha_gemini.h: Changed to use my_global.h sql/handler.cc: Fixed problem after merge sql/item.cc: Added Item_unit sql/item.h: Added Item_uint sql/matherr.c: Changed to use my_global.h sql/md5.c: Changed to use my_global.h sql/mini_client.cc: Changed to use my_global.h sql/my_lock.c: Changed to use my_global.h sql/mysql_priv.h: Changed to use my_global.h sql/net_serv.cc: Changed to use my_global.h sql/password.c: Changed to use my_global.h sql/sql_lex.cc: Added parsing support of UNSIGNED LONG LONG sql/sql_show.cc: Changed to use my_global.h sql/sql_string.cc: Changed to use my_global.h sql/sql_yacc.yy: Added usage of Int_uint sql/stacktrace.c: Changed to use my_global.h sql/udf_example.cc: Changed to use my_global.h strings/atof.c: Changed to use my_global.h strings/bchange.c: Changed to use my_global.h strings/bcmp.c: Changed to use my_global.h strings/bfill.c: Changed to use my_global.h strings/bmove.c: Changed to use my_global.h strings/bmove512.c: Changed to use my_global.h strings/bmove_upp.c: Changed to use my_global.h strings/ctype-big5.c: Changed to use my_global.h strings/ctype-czech.c: Changed to use my_global.h strings/ctype-euc_kr.c: Changed to use my_global.h strings/ctype-gb2312.c: Changed to use my_global.h strings/ctype-gbk.c: Changed to use my_global.h strings/ctype-latin1_de.c: Fixed problem with LIKE strings/ctype-sjis.c: Changed to use my_global.h strings/ctype-tis620.c: Changed to use my_global.h strings/ctype-ujis.c: Changed to use my_global.h strings/ctype.c: Changed to use my_global.h strings/do_ctype.c: Changed to use my_global.h strings/int2str.c: Changed to use my_global.h strings/is_prefix.c: Changed to use my_global.h strings/llstr.c: Changed to use my_global.h strings/longlong2str.c: Changed to use my_global.h strings/r_strinstr.c: Changed to use my_global.h strings/str2int.c: Changed to use my_global.h strings/str_test.c: Changed to use my_global.h strings/strappend.c: Changed to use my_global.h strings/strcend.c: Changed to use my_global.h strings/strcont.c: Changed to use my_global.h strings/strend.c: Changed to use my_global.h strings/strfill.c: Changed to use my_global.h strings/strings-not-used.h: Changed to use my_global.h strings/strinstr.c: Changed to use my_global.h strings/strmake.c: Changed to use my_global.h strings/strmov.c: Changed to use my_global.h strings/strnlen.c: Changed to use my_global.h strings/strnmov.c: Changed to use my_global.h strings/strstr.c: Changed to use my_global.h strings/strto.c: Changed to use my_global.h strings/strtol.c: Changed to use my_global.h strings/strtoll.c: Changed to use my_global.h strings/strtoul.c: Changed to use my_global.h strings/strtoull.c: Changed to use my_global.h strings/strxmov.c: Changed to use my_global.h strings/strxnmov.c: Changed to use my_global.h strings/udiv.c: Changed to use my_global.h tools/mysqlmanager.c: Changed to use my_global.h vio/test-ssl.c: Changed to use my_global.h vio/test-sslclient.c: Changed to use my_global.h vio/test-sslserver.c: Changed to use my_global.h vio/test-ssl: Changed to use my_global.h vio/vio.c: Changed to use my_global.h vio/viosocket.c: Changed to use my_global.h vio/viossl.c: Changed to use my_global.h vio/viosslfactories.c: Changed to use my_global.h vio/viotest-ssl.c: Changed to use my_global.h
222 lines
5.8 KiB
C
222 lines
5.8 KiB
C
/* Copyright (C) 2000 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
#include <my_global.h>
|
|
#include "stacktrace.h"
|
|
#include <signal.h>
|
|
#include <my_pthread.h>
|
|
|
|
#ifdef HAVE_STACKTRACE
|
|
#include <unistd.h>
|
|
|
|
#define PTR_SANE(p) ((p) && (char*)(p) >= heap_start && (char*)(p) <= heap_end)
|
|
|
|
char *heap_start;
|
|
|
|
void safe_print_str(const char* name, const char* val, int max_len)
|
|
{
|
|
char *heap_end= (char*) sbrk(0);
|
|
fprintf(stderr, "%s at %p ", name, val);
|
|
|
|
if (!PTR_SANE(val))
|
|
{
|
|
fprintf(stderr, " is invalid pointer\n");
|
|
return;
|
|
}
|
|
|
|
fprintf(stderr, "= ");
|
|
for(; max_len && PTR_SANE(val) && *val; --max_len)
|
|
fputc(*val++, stderr);
|
|
fputc('\n', stderr);
|
|
}
|
|
|
|
#ifdef HAVE_LINUXTHREADS
|
|
#define SIGRETURN_FRAME_COUNT 2
|
|
|
|
#if defined(__alpha__) && defined(__GNUC__)
|
|
/*
|
|
The only way to backtrace without a symbol table on alpha
|
|
is to find stq fp,N(sp), and the first byte
|
|
of the instruction opcode will give us the value of N. From this
|
|
we can find where the old value of fp is stored
|
|
*/
|
|
|
|
#define MAX_INSTR_IN_FUNC 10000
|
|
|
|
inline uchar** find_prev_fp(uint32* pc, uchar** fp)
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
|
|
{
|
|
uchar* p = (uchar*)pc;
|
|
if (p[2] == 222 && p[3] == 35)
|
|
{
|
|
return (uchar**)((uchar*)fp - *(short int*)p);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline uint32* find_prev_pc(uint32* pc, uchar** fp)
|
|
{
|
|
int i;
|
|
for(i = 0; i < MAX_INSTR_IN_FUNC; ++i,--pc)
|
|
{
|
|
char* p = (char*)pc;
|
|
if (p[1] == 0 && p[2] == 94 && p[3] == -73)
|
|
{
|
|
uint32* prev_pc = (uint32*)*((fp+p[0]/sizeof(fp)));
|
|
return prev_pc;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
|
|
|
|
|
void print_stacktrace(gptr stack_bottom, ulong thread_stack)
|
|
{
|
|
uchar** fp;
|
|
uint frame_count = 0;
|
|
#if defined(__alpha__) && defined(__GNUC__)
|
|
uint32* pc;
|
|
#endif
|
|
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__
|
|
__asm __volatile__ ("movl %%ebp,%0"
|
|
:"=r"(fp)
|
|
:"r"(fp));
|
|
if (!fp)
|
|
{
|
|
fprintf(stderr, "frame pointer (ebp) is NULL, did you compile with\n\
|
|
-fomit-frame-pointer? Aborting backtrace!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
#if defined(__alpha__) && defined(__GNUC__)
|
|
__asm __volatile__ ("mov $30,%0"
|
|
:"=r"(fp)
|
|
:"r"(fp));
|
|
if (!fp)
|
|
{
|
|
fprintf(stderr, "frame pointer (fp) is NULL, did you compile with\n\
|
|
-fomit-frame-pointer? Aborting backtrace!\n");
|
|
return;
|
|
}
|
|
#endif /* __alpha__ */
|
|
|
|
if (!stack_bottom)
|
|
{
|
|
ulong tmp= min(0x10000,thread_stack);
|
|
/* Assume that the stack starts at the previous even 65K */
|
|
stack_bottom= (gptr) (((ulong) &fp + tmp) &
|
|
~(ulong) 0xFFFF);
|
|
fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp);
|
|
}
|
|
if (fp > (uchar**) stack_bottom ||
|
|
fp < (uchar**) stack_bottom - thread_stack)
|
|
{
|
|
fprintf(stderr, "Bogus stack limit or frame pointer,\
|
|
fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
|
|
fp, stack_bottom, thread_stack);
|
|
return;
|
|
}
|
|
|
|
fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
|
|
#if defined(__alpha__) && defined(__GNUC__)
|
|
fprintf(stderr, "Warning: Alpha stacks are difficult -\
|
|
will be taking some wild guesses, stack trace may be incorrect or \
|
|
terminate abruptly\n");
|
|
// On Alpha, we need to get pc
|
|
__asm __volatile__ ("bsr %0, do_next; do_next: "
|
|
:"=r"(pc)
|
|
:"r"(pc));
|
|
#endif /* __alpha__ */
|
|
|
|
while (fp < (uchar**) stack_bottom)
|
|
{
|
|
#ifdef __i386__
|
|
uchar** new_fp = (uchar**)*fp;
|
|
fprintf(stderr, "%p\n", frame_count == SIGRETURN_FRAME_COUNT ?
|
|
*(fp+17) : *(fp+1));
|
|
#endif /* __386__ */
|
|
|
|
#if defined(__alpha__) && defined(__GNUC__)
|
|
uchar** new_fp = find_prev_fp(pc, fp);
|
|
if (frame_count == SIGRETURN_FRAME_COUNT - 1)
|
|
{
|
|
new_fp += 90;
|
|
}
|
|
|
|
if (fp && pc)
|
|
{
|
|
pc = find_prev_pc(pc, fp);
|
|
if (pc)
|
|
fprintf(stderr, "%p\n", pc);
|
|
else
|
|
{
|
|
fprintf(stderr, "Not smart enough to deal with the rest\
|
|
of this stack\n");
|
|
goto end;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
|
|
goto end;
|
|
}
|
|
#endif /* defined(__alpha__) && defined(__GNUC__) */
|
|
if (new_fp <= fp )
|
|
{
|
|
fprintf(stderr, "New value of fp=%p failed sanity check,\
|
|
terminating stack trace!\n", new_fp);
|
|
goto end;
|
|
}
|
|
fp = new_fp;
|
|
++frame_count;
|
|
}
|
|
|
|
fprintf(stderr, "Stack trace seems successful - bottom reached\n");
|
|
|
|
end:
|
|
fprintf(stderr, "Please read http://www.mysql.com/doc/U/s/Using_stack_trace.html and follow instructions on how to resolve the stack trace. Resolved\n\
|
|
stack trace is much more helpful in diagnosing the problem, so please do \n\
|
|
resolve it\n");
|
|
}
|
|
#endif /* HAVE_LINUXTHREADS */
|
|
#endif /* HAVE_STACKTRACE */
|
|
|
|
/* Produce a core for the thread */
|
|
|
|
#ifdef HAVE_LINUXTHREADS
|
|
void write_core(int sig)
|
|
{
|
|
signal(sig, SIG_DFL);
|
|
if (fork() != 0) exit(1); // Abort main program
|
|
// Core will be written at exit
|
|
}
|
|
#else
|
|
void write_core(int sig)
|
|
{
|
|
signal(sig, SIG_DFL);
|
|
pthread_kill(pthread_self(), sig);
|
|
}
|
|
#endif
|