Issue Details (XML | Word | Printable)

Key: CORE-4753
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Vlad Khorsun
Reporter: Denis
Votes: 0
Watchers: 4
Operations

If you were logged in you would be able to see more operations.
Firebird Core

Firebird hangs in embed mode

Created: 16/Apr/15 02:05 AM   Updated: 23/Sep/15 12:22 PM
Component/s: Engine
Affects Version/s: 2.5.4
Fix Version/s: 3.0 Beta 2, 2.5.5

File Attachments: 1. File FTBugTest.cpp (2 kB)

Environment:
Windows 8.1 Eng 64
or Windows 7 64 Home


 Description  « Hide
Firebird embed hangs in isc_attach_database if to execute new application during previous connection exists. Here is my example how to reproduce it (look at HANGS HERE comment):

#include <Windows.h>
#include <string>

#include "ibase.h"

#pragma comment(lib, "fbclient_ms.lib")

const std::string server_and_path = "d:\\DATABASE.FDB";
const std::string process = "C:\\Windows\\System32\\calc.exe";
const unsigned StatusLen = 20;

void connect1()
{
isc_db_handle db_handle = nullptr;
ISC_STATUS status_vect[StatusLen] = {};
char pdb[1] = { isc_dpb_version1 };

// connect
isc_attach_database(
status_vect,
server_and_path.size(),
server_and_path.c_str(),
&db_handle,
sizeof(pdb),
pdb
);

// start process

STARTUPINFOA si = {};
si.cb = sizeof(si);
PROCESS_INFORMATION pi = {};
int res = CreateProcessA(
process.c_str(), // lpApplicationName
NULL, // lpCommandLine
NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
TRUE, // bInheritHandles
DETACHED_PROCESS, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&si, // lpStartupInfo
&pi // lpProcessInformation
);

// disconnect
isc_detach_database(status_vect, &db_handle);
}


void connect2()
{
isc_db_handle db_handle = nullptr;
char pdb[1] = { isc_dpb_version1 };

ISC_STATUS status_vect[StatusLen] = {};

// connect
isc_attach_database( // <- HANGS HERE
status_vect,
server_and_path.size(),
server_and_path.c_str(),
&db_handle,
sizeof(pdb),
pdb
);

isc_detach_database(status_vect, &db_handle);
}


int main(int argc, char* argv[])
{
connect1();
connect2();
return 0;
}


 All   Comments   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Denis added a comment - 16/Apr/15 02:08 AM
Example to reproduce

Vlad Khorsun added a comment - 16/Apr/15 08:12 AM
The reason is that child process by default inherits all handles of parent process.
In our case child process keeps syncronization objects used by Firebird open after parent process detaches database.
At next attempt to attach database engine tries to initialize lock table and failed to "syncronize"
with child process (which have no idea about Firebird).

Obvious workaround is to run child process with bInheritHandles == FALSE, but this is not always possible and
could limit developers of embedded applications.

The proposed fix is to explicitly disable handle inheritance for named syncronization objects used by the engine.

Fix is committed into v2.5 tree, please verify it with next snapshot build.

Vlad Khorsun added a comment - 18/Apr/15 01:07 AM
Simplified test case, using FB3 embedded connection:

firebird>isql c:\temp\A.FDB
Database: c:\temp\A.FDB
SQL> shell start calc;
SQL> connect c:\temp\a.fdb;
Commit current transaction (y/n)?y
Committing.

Hung with high CPU load at this point until calc.exe is terminated.

Database: c:\temp\a.fdb
SQL> exit;