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, тогда это объясняет сбои в работе. Это и есть то обоснованное подозрение, о котором я написал в начале. Теперь классический вопрос: что делать?