IBX, FIBPlus, UIB, ADO, .Net и прочее-прочее-прочее, в общем все, что относится к созданию приложений, работающих с InterBase, Firebird и Yaffil - клиент-серверных, трехзвенных, консольных и т.п.
Модератор: kdv
-
Saltaev
- Сообщения: 6
- Зарегистрирован: 25 апр 2006, 13:24
Сообщение
Saltaev » 25 апр 2006, 14:39
/*
Выполнение этого кода неминуемо заканчивается "крушением" программы. Почему?
Вызов isc_attach_database из main, затем isc_detach_database из finisher в контексте main выполняется успешно, а вот на второй итерации функция finisher выполняется за пределами контекста main - и isc_detach_database в ней вызывает "крушение" программы
Очевидно, Firebird какие-то данные размещает в стеке, стек разрушается...
Информация о версиях: - gcc version 3.4.2 20041017 (Red Hat 3.4.2-6.fc3)
Firebird TCP/IP server version LI-V1.5.2.4731 Firebird 1.5
Kernel 2.6.9-1.667 on an i686
04.10.2006
*/[/color]
#include <ibase.h>
#include <stdio.h>
#include <stdlib.h>
isc_db_handle db = NULL;
void
finisher(void){
- ISC_STATUS res = 0;
ISC_STATUS_ARRAY status_vector;
res = isc_detach_database(status_vector, &db); //
printf("isc_detach_database: %ld \n", res);
return;
}
int
main (int argc, char **argv){
- atexit(finisher);
ISC_STATUS res = 0;
ISC_STATUS_ARRAY status_vector;
for (int i = 1; i <= 2; i++){- res = isc_attach_database(status_vector, 8, "employee", &db, 32, "\x01\x1C\x06SYSDBA\x1D\x08masterke\x30\x0Bunicode_fss");
printf("isc_attach_database: %ld \n", res);
if (i != 2){
finisher();
}
}
printf("main_finished\n");
}
-
v6y
- Сообщения: 78
- Зарегистрирован: 12 мар 2005, 17:45
Сообщение
v6y » 25 апр 2006, 18:06
На FB 2.0 RC1 тоже "падает". Причем анализ корки говорит что падение происходит в
Код: Выделить всё
0 0xb7f0ef7c in KEYWORD_getTokens () from /usr/lib/libfbembed.so.2
Но кто здесь виноват - atexit или fb - утверждать не берусь, а копаться недосуг.
P.S.
Если строкой коннекта указать
Код: Выделить всё
res = isc_attach_database(status_vector, 0, "localhost:employee", &db, 32, "\x01\x1C\x06SYSDBA\x1D\x08masterke\x30\x0Bunicode_fss");
То все отрабатывает нормально
P.P.S. Оригинальный способ заполнения dpb

-
hvlad
- Разработчик Firebird
- Сообщения: 1244
- Зарегистрирован: 21 мар 2005, 10:48
Сообщение
hvlad » 25 апр 2006, 18:55
v6y писал(а):На FB 2.0 RC1 тоже "падает". Причем анализ корки говорит что падение происходит в
Код: Выделить всё
0 0xb7f0ef7c in KEYWORD_getTokens () from /usr/lib/libfbembed.so.2
Но кто здесь виноват - atexit или fb - утверждать не берусь, а копаться недосуг.
Она возращает static const переменную. Похоже, что в момент вызова atexit, сегмент данных уже разрушен.
Подробнее я бы искал в доке на atexit в реализации данного компилятора.
MSVC писал(а):No global static objects initialized prior to the call to atexit are destroyed prior to execution of the exit-processing function
Честно говоря, не вижу смысла делать detach из atexit ...
v6y писал(а):P.S.
Если строкой коннекта указать
Код: Выделить всё
res = isc_attach_database(status_vector, 0, "localhost:employee", &db, 32, "\x01\x1C\x06SYSDBA\x1D\x08masterke\x30\x0Bunicode_fss");
То все отрабатывает нормально
Ибо на линуксе локальное подключение - это сервер в твоём процессе, а localhost - сервер в своём процессе
-
v6y
- Сообщения: 78
- Зарегистрирован: 12 мар 2005, 17:45
Сообщение
v6y » 26 апр 2006, 08:21
hvlad писал(а): Похоже, что в момент вызова atexit, сегмент данных уже разрушен.
Дело в том, что если подключать библиотеку fbclient, то все работает нормально, а если fbembed, то имеет место "Segmentation fault".
Подробнее я бы искал в доке на atexit в реализации данного компилятора.
MSVC писал(а):No global static objects initialized prior to the call to atexit are destroyed prior to execution of the exit-processing function
Я все таки не уверен на все 100 что это именно atexit во всем виноват
Честно говоря, не вижу смысла делать detach из atexit ...
Дело не в смысле, а в том что имеет место поведение, отличное от ожидаемого. Не подумай, что это наезд, но я считаю, что если есть какие-то аномалии, то их желательно устранить или хотя бы установить точную причину возникновения. Хотя... Если ты абсолютно уверен, что дело исключительно в atexit, то пусть так оно и будет
-
Saltaev
- Сообщения: 6
- Зарегистрирован: 25 апр 2006, 13:24
Сообщение
Saltaev » 26 апр 2006, 09:40
v6y писал(а):P.P.S. Оригинальный способ заполнения dpb

Да, пожалуй. Вначале я использовал isc_expand_dpb, потом она мне разонравилась, написал свою функцию, которую использую также при формировании spb в isc_service_attach и isc_service_start. Выкладывать не стал - хотел выложить компактный работающий пример.
v6y писал(а):Но кто здесь виноват - atexit или fb - утверждать не берусь, а копаться недосуг.
Да, ничего не поделаешь. Кстати, писал об этом
preeves@ibphoenix.com. То ли я плохо по-английски пишу, то ли не по адресу обратился - ответ какой-то ни рыба ни мясо.
hvlad писал(а):Честно говоря, не вижу смысла делать detach из atexit ...
Со временем моя программа разраслась, появился графический интерфейс и т. д. Отключение от БД происходит задолго до atexit и проблемы как таковой не стало. Однако поделиться ей с коллегами считаю необходимо.
-
hvlad
- Разработчик Firebird
- Сообщения: 1244
- Зарегистрирован: 21 мар 2005, 10:48
Сообщение
hvlad » 26 апр 2006, 13:20
v6y писал(а):hvlad писал(а): Похоже, что в момент вызова atexit, сегмент данных уже разрушен.
Дело в том, что если подключать библиотеку fbclient, то все работает нормально, а если fbembed, то имеет место "Segmentation fault".
Потому, что та самая переменная живёт в fbembed, т.е. в сервере.
v6y писал(а):Я все таки не уверен на все 100 что это именно atexit во всем виноват
Честно говоря, не вижу смысла делать detach из atexit ...
Дело не в смысле, а в том что имеет место поведение, отличное от ожидаемого. Не подумай, что это наезд, но я считаю, что если есть какие-то аномалии, то их желательно устранить или хотя бы установить точную причину возникновения. Хотя... Если ты абсолютно уверен, что дело исключительно в atexit, то пусть так оно и будет
Я другого вывода из имеющейся информации сделать не могу.
Похоже, что к моменту вызова atexit библиотека уже выгружена из памяти.
Я этого проверить не могу, да и не хочу - есть чем заниматься
-
hvlad
- Разработчик Firebird
- Сообщения: 1244
- Зарегистрирован: 21 мар 2005, 10:48
Сообщение
hvlad » 26 апр 2006, 13:24
Если уж сильно хочется разобраться, пиши в fb-devel или в баг-трекер
-
Dimitry Sibiryakov
- Заслуженный разработчик
- Сообщения: 1436
- Зарегистрирован: 15 сен 2005, 09:05
Сообщение
Dimitry Sibiryakov » 26 апр 2006, 14:17
Лично я вообще не вижу смысла ставить detach в atexit. Если приложение завершается некорректно то коннект упадет сам собой. Баги надо править а не соломку подстилать.
-
v6y
- Сообщения: 78
- Зарегистрирован: 12 мар 2005, 17:45
Сообщение
v6y » 26 апр 2006, 15:58
Dimitry Sibiryakov писал(а):Лично я вообще не вижу смысла ставить detach в atexit. Если приложение завершается некорректно то коннект упадет сам собой. Баги надо править а не соломку подстилать.
Ребята, ну вы же профи... Имеет место "неправильное" поведение. Хорошо если его причиной действительно является реализация atexit... А если нет? А если это действительно баг FB и он может привести к сбою в какой-нибудь другой ситуации? Вот в этом то вам как профи в первую очередь и надо видеть некий смысл, ИМХО. Ну а если считаете этот момент малозначительным - да и нехай с ним - лично мне он тоже жить не мешает.
-
kdv
- Forum Admin
- Сообщения: 6595
- Зарегистрирован: 25 окт 2004, 18:07
Сообщение
kdv » 26 апр 2006, 16:13
Вызов isc_attach_database из main, затем isc_detach_database из finisher в контексте main выполняется успешно, а вот на второй итерации функция finisher выполняется за пределами контекста main - и isc_detach_database в ней вызывает "крушение" программы
Очевидно, Firebird какие-то данные размещает в стеке, стек разрушается...
я в сях не профи, но я тебе скажу, что такой метод закрытия коннекта весьма крив. Когда там этот atexit вызывается, и в каком контексте - фиг его знает. О чем тебе Влад сразу и сказал.
Ты можешь поступить по другому - запихнуть какую-нибудь кривую переменную в isc_detach и если функция "упадет", то клевать разработчиков, что у них там криво параметры проверяются.
А так, нет смысла - ну падает, ну и что? Тем более что твой вариант сильно напоминает методу, когда getmem делается в одном месте, а freemem хрен знает где и из непонятного контекста... Причем, как ты сам сказал, ДВА раза...
-
v6y
- Сообщения: 78
- Зарегистрирован: 12 мар 2005, 17:45
Сообщение
v6y » 26 апр 2006, 17:45
Вобщем не удержался и разобрался

Тут ни atexit, ни FB не виноваты.
Если народу интересно, то расскажу в чем тут на самом деле дело.
P.S. На разбор около 5 минут ушло, однако

-
kdv
- Forum Admin
- Сообщения: 6595
- Зарегистрирован: 25 окт 2004, 18:07
Сообщение
kdv » 26 апр 2006, 17:50
как бы, принято делиться найденным решением проблемы, каким бы оно ни было...

-
v6y
- Сообщения: 78
- Зарегистрирован: 12 мар 2005, 17:45
Сообщение
v6y » 26 апр 2006, 18:26
kdv писал(а):как бы, принято делиться найденным решением проблемы, каким бы оно ни было...

Дело в том, что при вызове isc_attach_databse вызывается atexit(gds__cleanup). Поскольку при выходе из программы функции, зарегистрированные atexit-ом, вызваются в обратном порядке, то данном случае вначале вызовется gds__cleanup и лишь затем finisher.
Таким образом к моменту вызова finisher, gds__cleanup уже очистил соответсвующую область памяти и автор самым естественным образом получил SIGSEGV. Поэтому, если в указанном примере переместить
atexit(finisher) за цикл, то все отработает нормально, поскольку в данном случае вначале выполнится finisher и лишь затем gds__cleanup. Так что Влад прав, предположив, что данные к моменту вызова finisher разрушенны и что дело тут в реализации atexit, хоть и основаны его предположения на несклолько других посылках
P.S. Что бы это увидеть, достаточно было закомпилить данный пример с отладочной информацией, прилинковать libfbembed.so.2.0.0.debug и запустить через отладчик
