[devel] debug MySQL SEGV
Alexey Tourbin
=?iso-8859-1?q?at_=CE=C1_altlinux=2Eru?=
Сб Авг 26 22:48:48 MSD 2006
On Sat, Aug 26, 2006 at 06:43:06PM +0400, Alexey Tourbin wrote:
> On Sat, Aug 26, 2006 at 06:17:31PM +0400, Alexey Tourbin wrote:
> > > интересно, а что скажет abi-drift?
> > Он вроде заглох послденее время. message size >1M.
>
> Впрочем, abi_drift проверят только разрешимость символов. То есть с
> abi_drift можно спрашивать, когда приложение падает по undefined symbol.
> Здесь что-то более тонкое. Я попробовал в gdb расковырять но там
> сплошные callback'и, в общем боюсь что мне слабо такое расковырять.
> Но попробую ещё...
gdb не помогает. :( Поэтому я выбрал другую тактику, и у меня появилось
обоснованное подозрение. Изложу подробно, как я реализую эту тактику;
это может быть назидательным для других maintainer'ов.
Тактика состоит в том, чтобы проверить, *что именно* мы компилируем.
Сначала стивится libMySQL-devel 5.0.22 и делается gcc -E всех
компилируемых файлов (препроцессор). Потом ставится libMySQL-devel
5.0.24 и опять делается gcc -E всех комплируемых файлов. Потом на
раскрытые таким образом исходники сравниваются.
$ cd ~build/DBD-mysql-3.0006
$ rm -fv *.o
removed `dbdimp.o'
removed `mysql.o'
$ sudo rpm -Uv ~sisyphus/files/i586/RPMS/libMySQL*-5.0.22-alt1.i586.rpm --force --nodeps
Preparing packages for installation...
libMySQL-5.0.22-alt1
libMySQL-devel-5.0.22-alt1
$
Поставил старые пакеты libMySQL. Теперь нужно зопатчить Makefile,
чтобы вместо gcc -c выполнялся gcc -E.
$ diff Makefile{-,}
--- Makefile- 2006-08-26 14:21:28 +0000
+++ Makefile 2006-08-26 18:26:45 +0000
@@ -309,7 +309,7 @@ BSLOADLIBS =
# --- MakeMaker const_cccmd section:
-CCCMD = $(CC) -c $(PASTHRU_INC) $(INC) \
+CCCMD = $(CC) -E $(PASTHRU_INC) $(INC) \
$(CCFLAGS) $(OPTIMIZE) \
$(PERLTYPE) $(MPOLLUTE) $(DEFINE_VERSION) \
$(XS_DEFINE_VERSION)
$
Теперь при попытке комплияции .c.o в stdout будут сыпаться раскрытые
исходники.
$ make dbdimp.o |tail -5
SV *mysql_db_last_insert_id(SV *dbh, imp_dbh_t *imp_dbh,
SV *catalog, SV *schema, SV *table, SV *field, SV *attr)
{
return Perl_sv_2mortal(((PerlInterpreter *)pthread_getspecific((*Perl_Gthr_key_ptr(((void *)0))))), my_ulonglong2str(mysql_insert_id(&((imp_dbh_t*)imp_dbh)->mysql)));
}
$
Значит, вывод можно сохранять.
$ make dbdimp.o >dbdimp.E1
$ make mysql.o >mysql.E1
$ ls -l *.E1
-rw-r--r-- 1 at at 596132 Aug 26 22:30 dbdimp.E1
-rw-r--r-- 1 at at 608773 Aug 26 22:30 mysql.E1
$
Теперь осталось поставить новую библиотеку и опять сохранить вывод.
$ sudo rpm -Uv ~sisyphus/files/i586/RPMS/libMySQL*-5.0.24-alt1.i586.rpm
Preparing packages for installation...
libMySQL-5.0.24-alt1
libMySQL-devel-5.0.24-alt1
$ make dbdimp.o >dbdimp.E2
$ make mysql.o >mysql.E2
А теперь -- то, ради чего всё делалось: сравниваем полностью раскрытые
исходники.
$ diff -upbB dbdimp.E[12]
--- dbdimp.E1 2006-08-26 18:30:07 +0000
+++ dbdimp.E2 2006-08-26 18:40:43 +0000
@@ -15290,7 +15290,8 @@ enum mysql_option
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT
+ MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
@@ -15305,6 +15306,7 @@ struct st_mysql_options {
char *ssl_ca;
char *ssl_capath;
char *ssl_cipher;
+ my_bool ssl_verify_server_cert;
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl;
@@ -15450,7 +15452,7 @@ typedef struct st_mysql_res {
my_bool unbuffered_fetch_cancelled;
const struct st_mysql_methods *methods;
} MYSQL_RES;
-# 327 "/usr/include/mysql/mysql.h"
+# 329 "/usr/include/mysql/mysql.h"
typedef struct st_mysql_manager
{
NET net;
@@ -15470,10 +15472,10 @@ typedef struct st_mysql_parameters
unsigned long *p_max_allowed_packet;
unsigned long *p_net_buffer_length;
} MYSQL_PARAMETERS;
-# 357 "/usr/include/mysql/mysql.h"
+# 359 "/usr/include/mysql/mysql.h"
int mysql_server_init(int argc, char **argv, char **groups);
void mysql_server_end(void);
-# 371 "/usr/include/mysql/mysql.h"
+# 373 "/usr/include/mysql/mysql.h"
MYSQL_PARAMETERS * mysql_get_parameters(void);
@@ -15515,6 +15517,7 @@ MYSQL * mysql_init(MYSQL *mysql);
my_bool mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
+const char * mysql_get_ssl_cipher(MYSQL *mysql);
my_bool mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
MYSQL * mysql_real_connect(MYSQL *mysql, const char *host,
@@ -15664,13 +15667,13 @@ int mysql_manager_fetch_line(MYSQL_MANAG
char* res_buf,
int res_buf_size);
my_bool mysql_read_query_result(MYSQL *mysql);
-# 569 "/usr/include/mysql/mysql.h"
+# 572 "/usr/include/mysql/mysql.h"
enum enum_mysql_stmt_state
{
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
MYSQL_STMT_FETCH_DONE
};
-# 639 "/usr/include/mysql/mysql.h"
+# 642 "/usr/include/mysql/mysql.h"
typedef struct st_mysql_bind
{
unsigned long *length;
@@ -15844,7 +15847,7 @@ my_bool mysql_autocommit(MYSQL * mysql,
my_bool mysql_more_results(MYSQL *mysql);
int mysql_next_result(MYSQL *mysql);
void mysql_close(MYSQL *sock);
-# 837 "/usr/include/mysql/mysql.h"
+# 840 "/usr/include/mysql/mysql.h"
unsigned long net_safe_read(MYSQL* mysql);
# 22 "dbdimp.h" 2
# 1 "/usr/include/mysql/mysqld_error.h" 1
/var/mail/at has mail!
$
И второй файл:
$ diff -upbB mysql.E[12]
--- mysql.E1 2006-08-26 18:30:19 +0000
+++ mysql.E2 2006-08-26 18:40:47 +0000
@@ -15291,7 +15291,8 @@ enum mysql_option
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
- MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT
+ MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
+ MYSQL_OPT_SSL_VERIFY_SERVER_CERT
};
struct st_mysql_options {
@@ -15306,6 +15307,7 @@ struct st_mysql_options {
char *ssl_ca;
char *ssl_capath;
char *ssl_cipher;
+ my_bool ssl_verify_server_cert;
char *shared_memory_base_name;
unsigned long max_allowed_packet;
my_bool use_ssl;
@@ -15451,7 +15453,7 @@ typedef struct st_mysql_res {
my_bool unbuffered_fetch_cancelled;
const struct st_mysql_methods *methods;
} MYSQL_RES;
-# 327 "/usr/include/mysql/mysql.h"
+# 329 "/usr/include/mysql/mysql.h"
typedef struct st_mysql_manager
{
NET net;
@@ -15471,10 +15473,10 @@ typedef struct st_mysql_parameters
unsigned long *p_max_allowed_packet;
unsigned long *p_net_buffer_length;
} MYSQL_PARAMETERS;
-# 357 "/usr/include/mysql/mysql.h"
+# 359 "/usr/include/mysql/mysql.h"
int mysql_server_init(int argc, char **argv, char **groups);
void mysql_server_end(void);
-# 371 "/usr/include/mysql/mysql.h"
+# 373 "/usr/include/mysql/mysql.h"
MYSQL_PARAMETERS * mysql_get_parameters(void);
@@ -15516,6 +15518,7 @@ MYSQL * mysql_init(MYSQL *mysql);
my_bool mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca,
const char *capath, const char *cipher);
+const char * mysql_get_ssl_cipher(MYSQL *mysql);
my_bool mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db);
MYSQL * mysql_real_connect(MYSQL *mysql, const char *host,
@@ -15665,13 +15668,13 @@ int mysql_manager_fetch_line(MYSQL_MANAG
char* res_buf,
int res_buf_size);
my_bool mysql_read_query_result(MYSQL *mysql);
-# 569 "/usr/include/mysql/mysql.h"
+# 572 "/usr/include/mysql/mysql.h"
enum enum_mysql_stmt_state
{
MYSQL_STMT_INIT_DONE= 1, MYSQL_STMT_PREPARE_DONE, MYSQL_STMT_EXECUTE_DONE,
MYSQL_STMT_FETCH_DONE
};
-# 639 "/usr/include/mysql/mysql.h"
+# 642 "/usr/include/mysql/mysql.h"
typedef struct st_mysql_bind
{
unsigned long *length;
@@ -15845,7 +15848,7 @@ my_bool mysql_autocommit(MYSQL * mysql,
my_bool mysql_more_results(MYSQL *mysql);
int mysql_next_result(MYSQL *mysql);
void mysql_close(MYSQL *sock);
-# 837 "/usr/include/mysql/mysql.h"
+# 840 "/usr/include/mysql/mysql.h"
unsigned long net_safe_read(MYSQL* mysql);
# 22 "dbdimp.h" 2
# 1 "/usr/include/mysql/mysqld_error.h" 1
$
Глядя на diff, *единственное*, что приходит в голову -- это изменение
в структуре st_mysql_options. Прямо посреди структуры добавилось новое
поле. Если эта структура каким-либо косвенным образом экспозируется
в качестве API, тогда это объясняет сбои в работе. Это и есть то
обоснованное подозрение, о котором я написал в начале.
Теперь классический вопрос: что делать?
----------- следующая часть -----------
Было удалено вложение не в текстовом формате...
Имя : =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Тип : application/pgp-signature
Размер : 189 байтов
Описание: =?iso-8859-1?q?=CF=D4=D3=D5=D4=D3=D4=D7=D5=C5=D4?=
Url : <http://lists.altlinux.org/pipermail/devel/attachments/20060826/a72e045b/attachment-0001.bin>
Подробная информация о списке рассылки Devel