Решил обновить FB3 [сборка 31465].
Решил вот обновить свою инсталляцию FB3 до текущий. Последний раз я это делал почти год назад — 30 декабря 2013. Помнится, решил тогда не портить себе нервы и забить на FB3 до лучших времен.
1. Обновил исходники.
2. Поизучал батники — ага, собирать будет VS2013. Гуд.
3. Запустил компиляцию отладочных сборок (32 и 64 бита).
4. ICU, значит, больше не собирается, а поставляется готовое. Без PDB. Наверное, чтобы баги было интереснее ловить.
5. Подозрительно чистый вывод компилятора. Могли бы, конечно, придушить «warning LNK4075: ignoring ‘/EDITANDCONTINUE’ due to ‘/SAFESEH’ specification». Но в целом — в душе что-то затеплилось.
6. Запустил VirtualBox и уже начал прицеливаться к виртуальной машине с XP, на которой жила старая сборка с FB3.
7. Стоп — я же собирал 2013-ой. Открыл проектные файлы. Ну точно — ToolSet не для XP. Ладно у меня тут есть Win7 64бита.
8. Закачал на эту тестовую Win7_64 отладочные сборки (64бита)
9. По старой памяти полез в конфиг и выставил (затупил, да) SharedCache=true, SharedDatabase=true
10. Запустил gsec.exe. Огреб ассерт. Убил его в диспетчере и еще раз запустил. Ассерт.
11. Подключился удаленным отладчиком.
12. Вспомнил Диму Еманова и Сашу Пешкова.
13. Создал каталог «c:\ProgramData\firebird»
14. Запустил «gsec -add SYSDBA -pw masterkey»:
unable to open database
feature is not supported
SharedDatabase and SharedCache settings cannot be both enabled at once
15. Исправил конфиг: SharedCache=true, SharedDatabase=false
16. Перезапустил сервер.
17. Создал SYSDBA и GAMER-a
18. Настроил FireWall.
19. Запустил с внешней машины сборку тестовой базы. Используется родной isql.exe
CHARACTER SET TIS620 is not installed
CHARACTER SET GB18030 is not installed
Ладно, черт с тобой, Адриано.
20. Исправил конфиги генератора базы и запустил создание еще раз. Создалось без проблем.
21. Зарегистрировал отладочный IBProvider, с добрыми мыслями о разработчиках FB.
22. Запускаю детский набор тестов, написанный на VBScript. Огребаю assert.

Интересно. Это типа нам вернули больше чем мы просили. TODO: assert надо доработать и выводить цифры.
Подключаемся отладчиком. SegmentSize=16384, isc_get_segment вернул actual_readed=52428.
Посмотрел на собственный код:
void t_ib_blob_reader_v5::read(length_type const BufferSize,
void* pBuffer,
length_type* const pReadBytes)
{
assert(m_provider);
assert(m_connection);
assert(m_transaction);
assert(m_handle!=NULL); //blob is open
assert(this->is_open()); //verification
CHECK_WRITE_PTR(pBuffer,BufferSize);
if(pReadBytes!=NULL)
(*pReadBytes)=0;
if(BufferSize==0)
return;
const int max_segment_size=structure::t_numeric_limits<isc_blob_seg_size>::max_value();
{
const BYTE* const pEndBuffer=reinterpret_cast<const BYTE*>(pBuffer)+BufferSize;
status_vector_type sv;
isc_status st;
isc_blob_seg_size actual_readed;
size_t npass_of_zero_actual_readed=0;
for(;;)
{
assert(reinterpret_cast<BYTE*>(pBuffer)<pEndBuffer);
const isc_blob_seg_size SegmentSize=
static_cast<isc_blob_seg_size>(min(max_segment_size,pEndBuffer-reinterpret_cast<const BYTE*>(pBuffer)));
{//минимизация времени блокирования подключения
const t_db_lock_guard __lock(m_guard);
//check again
assert(m_handle!=NULL); //blob is open
assert(this->is_open()); //verification
switch(st=m_provider->m_isc_get_segment.point()(sv.reset(),
&m_handle,
&(actual_readed=0),
SegmentSize,
pBuffer))
{
case 0:
case isc_segment:
case isc_segstr_eof:
{
break;
}
default:
{
m_connection->dangerous__throw_server_error(ibp_mce_br__fail_get_segment_1,
sv,
E_FAIL);
}
}//switch
}//local
assert(actual_readed<=SegmentSize);
if(SegmentSize<actual_readed)
{
t_ibp_error exc(E_FAIL,ibp_mce_br__get_bad_segment_size_2);
exc<<actual_readed<<SegmentSize;
exc.raise_me();
}//if
pBuffer=reinterpret_cast<BYTE*>(pBuffer)+actual_readed;
if(pReadBytes!=NULL)
(*pReadBytes)+=actual_readed;
//---- проверяем - не пора ли вываливаться из цикла
if(st==isc_segstr_eof)
break;
if(reinterpret_cast<BYTE*>(pBuffer)==pEndBuffer)
break;
//----
if(actual_readed==0)
++npass_of_zero_actual_readed;
else
npass_of_zero_actual_readed=0; //сброс счетчика нулевых блоков данных
//отлавливаем подозрительные намеки на зацикливание
if(npass_of_zero_actual_readed>100)
{
IBP_BUG_CHECK__DEBUG(L"t_ib_blob_reader_v5::get_segment",
L"#001",
L"isc_get_segment");
}//if
}//for
}//local
}//read
Ладно, жмем «Пропустить».
Сработало еще раз. Пропускаем. Пропускаем. Пропускаем. Пропускаем….
23. Приехали.
Следующие тесты завершились ошибкой (8 из 567):
1. cmd.append_chunk.txt_blob
2. db.datatypes.blob.text.charset.length
3. cn.rs.maxrecords.v3_async.Recs_100.MaxRecs_100.FetchedRecs_100
4. schema.all.read
5. schema.ldr_cfg.check_constraints.1.CHECK_CONSTRAINTS_BY_TABLE
6. schema.ldr_cfg.check_constraints.1.CHECK_CONSTRAINTS
7. ibps.row_cursor.01
8. ibps.row_cursor.02
24. Все. Всем спасибо, все свободны.
Dmitry Kovalenko on 4 декабря, 2014
Выспался и посмотрел повнимательней.
isc_get_segment через (*returnLength) возвращает значение неинициализированной локальной переменной length.
Ну я даже не знаю…
— то ли это бага fbclient.
— то ли я должен по-другому реагировать на isc_segstr_eof.