I have this code in a big project that makes a connection to a MySQL database, and does not work:
boost::shared_ptr<sql::Connection> connection;
sql::Driver *driver = get_driver_instance();
assert(driver != 0);
std::string server = "servname", user = "pietro", password = "abc";
try
{
connection.reset(driver->connect(server, user, password));
assert(connection != 0);
if(connection->isClosed() == false) // <-- segmentation fault
{
}
}
I get a segmentation fault where indicated (all parameters are valid).
However, this same code works in a test project.
Going into the sql::Connection::isClosed() member function with a debugger, I obtain no information about the possible cause; here is where I get:
mysql-connector-c++-1.0.5/driver/mysql_connection.cpp - line 430
/* {{{ MySQL_Connection::checkClosed() -I- */
void
MySQL_Connection::checkClosed()
{
CPP_ENTER_WL(intern->logger, "MySQL_Connection::checkClosed");
if (!intern->is_valid) {
throw sql::SQLException("Connection has been closed");
}
}
This checkClosed() function is successfully executed seven times from connection.reset() just before. The value of the "intern" pointer does not change and is not null at this stage.
When I check if the connection is closed, the checkClosed() function is run again. Now the "intern" pointer value is 0x8, a location I cannot access.
Here I get a SIGSEGV, segmentation fault.
Let me know if you would like the disassembled code...
Platform:
MySQL 5.x
MySQL Connector/C++ 1.0.5
Linux - OpenSuse 11.4
P.S.:
I noticed that all the shared_ptr's member functions work as expected:
connection.get(); // = 0x8fb4a0
connection.use_count(); // = 1
connection.unique(); // = 1
while all the calls done on the pointed object cause the segmentation fault (SIGABRT):
connection->getClientInfo();
connection->isClosed();
either your connection deleted, or you have memory corruption. use valgrind to find answer
Related
I'm trying to use the Leadtools API version 21 for automatically scanning some documents and here is a sudo code of what I have done (it runs in a secondary thread and the unlock has been done in the main thread):
void CheckRetCode(int rc)
{
if (SUCCESS != rc)
{
L_TCHAR errMsg[1024];
memset(errMsg, 0, sizeof(errMsg));
L_GetFriendlyErrorMessage(rc, errMsg, 1024, L_FALSE);
throw TLeadException(errMsg, rc);
}
}
void OnThreadExecute(void)
{
HTWAINSESSION hSession = nullptr;
APPLICATIONDATA appData;
L_INT nRet;
L_TCHAR pszTwnSourceName[1024];
LTWAINSOURCE sInfo;
memset(&appData, 0, sizeof(APPLICATIONDATA));
appData.uStructSize = sizeof(APPLICATIONDATA);
appData.hWnd = hWnd;// hWnd is valid handle of my main window
appData.uLanguage = TWLG_ENGLISH_USA;
appData.uCountry = TWCY_USA;
wcscpy(appData.szManufacturerName, L"MyCompanyName");
wcscpy(appData.szAppProductFamily, L"MyProductName");
wcscpy(appData.szAppName, appData.szAppProductFamily);
wcscpy(appData.szVersionInfo, L"Version 0.1.0.1");
nRet = L_TwainInitSession2(&hSession, &appData, LTWAIN_INIT_MULTI_THREADED);
CheckRetCode(nRet);// the exception gets catched elsewhere but no error reported here
memset(pszTwnSourceName, 0, sizeof(pszTwnSourceName));
wcscpy(pszTwnSourceName, L"EPSON Artisan837/PX830"); // the name of the scanner is verifyed
sInfo.uStructSize = sizeof(LTWAINSOURCE);
sInfo.pszTwainSourceName = pszTwnSourceName;
CheckRetCode(L_TwainSelectSource(hSession, &sInfo)); // No error reported here
CheckRetCode(L_TwainStartCapsNeg(hSession)); // in here I get the return value -84 which is reported as "TWAIN DS or DSM reported error, app shouldn't (no need for your app to report the error)."
// the rest of the code but we cannot get there since above code reports error
}
Can anyone tell me what I'm doing wrong? Is there a step that I'm missing here?
EditThe function L_TwainSelectSource() make no effort to make sure the supplied source is valid and does not even return an error. As result, if you set the selected source to a garbage name, it will act as if it accepted it. From that point on if you try to Get/Set anything or try to acquire an image, every function returns -84.
Thank you
Sam
To test your code, I put the main window’s handle in a global variable:
globalhWnd = hWnd;
And modified your function to use that handle like this:
void OnThreadExecute(void *)
{
...
appData.hWnd = globalhWnd; // hWnd is valid handle of my main window
...
}
Then created a thread for it from the main program like this:
globalhWnd = hWnd;
_beginthread(OnThreadExecute, 0, 0);
I tried this with 5 different Twain sources: 2 virtual and 3 physical scanners (one of them an old Epson). All 5 drivers returned SUCCESS when calling L_TwainStartCapsNeg() from within the thread.
Two possibilities come to mind:
The problem might be caused by something else in your code other than the thread function.
Or the problem could be specific to your Twain driver.
To rule out the first possibility, I suggest creating a small test project that only creates a similar thread and does nothing else and trying it with different scanners. If it causes the same problem with all scanners, send that test project (not your full application) to support#leadtools.com and our support engineers with test it for you.
If the problem only happens with a specific Twain driver, try contacting the scanner’s vendor to see if they have an updated driver.
I'm trying to update an old c++ MFC program and SQLConfigDataSource is causing an unhandled exception when I try to create a DSN. The error message says:
Unhandled exception at 0x00007FFC97D89129 (KernelBase.dll):
0x0000087A (parameters: 0xFFFFFFFF887A0001, 0x0000000000000053)
The code runs correctly and functions as it should, but I can't seem to get rid of this error.
int mlen;
char* szDesc = new char[256];
sprintf_s(szDesc, 256, "DSN=%s?DBQ=%s?FIL=MicrosoftAccess?",
IV_DATABASE_NAME, // DSN name
sDBPath); // full file name for accdb file
mlen = strlen(szDesc);
for (int i = 0; i < mlen; i++) {
if (szDesc[i] == '?')
szDesc[i] = '\0';
}
SQLConfigDataSource(NULL, ODBC_ADD_DSN,
"Microsoft Access Driver (*.mdb, *.accdb)",
(LPCSTR)szDesc);
delete szDesc;
The arguments for SQLConfigDataSource are ill formed. See:
SQLConfigDataSource Function
And:
ConfigDSN Function
Each pair is terminated with a null byte, and the entire list is
terminated with a null byte. (That is, two null bytes mark the end of
the list.)
I've had this working for over a decade now and call it like:
if( ! bOk )//failed to open the default database for lack of DSN
{
TRACE("Could not find DSN\n");
BOOL ret= SQLConfigDataSource(
NULL,
ODBC_ADD_DSN,
(LPSTR) "Microsoft Access Driver (*.mdb)\0",
(LPSTR) "DSN=MS Access Database\0"
"Description=MS Access Database\0"
);
if( ! ret )
{
AfxMessageBox( _T("The 'Data Source Name' failed to install\nPlease call My Company\n800-555-5555") );
return FALSE;
}
}
Note that the first two extra nulls are redundant, but they do no harm. But the last line follows the two null, end of list, rule.
"Description=MS Access Database\0"
You should be checking the return value of SQLConfigDataSource. And you can call SQLInstallerError as described in Diagnostics. Also, the comments state that the keywords and values should not contain ?.
The error was occurring when Microsoft Access Database Engine 2016 Redistributable was installed. I installed the 2010 Redistributable and it runs perfectly without any issues.
I've been trying to use the mysql++ library in my application (windows x64 based) but I can't seem to connect to my sql server.
Some information:
I used this code to connect to the server:
mysqlpp::Connection conn(db, 0, user, pass, 3306);
this definitely has the right data in it.
and then, my sql server is the standard service from the MySQL install. And I'm pretty sure I used the standard settings. I can connect to it using the MySql Workbench and I edited some new tables and such but my own program doesn't seem to connect.
I read the documentation and I can't find anything specific that might suggest something why I can't connect.
Oh, so many issues, so little time...
Have you checked that your program has permissions to access the database?
Does your program have the correct privileges?
Is your host name correct?
What errors are you getting?
What exception is thrown?
When you use the debugger, what line is the error on?
Here's my method:
sql::Connection * const
Manager ::
get_db_connection(void) const
{
//-------------------------------------------------------------------------
// Use only one connection until proven that more connections will make
// the program more efficient or have a beneficial impact on the user.
// Thus the change in returning sql::Connection * rather than a smart pointer.
// A smart pointer will delete its contents.
//-------------------------------------------------------------------------
static const char host_text[] = "tcp://127.0.0.1:3306/";
static std::string host_name;
if (!m_connection_initialized)
{
host_name = host_text;
initialize_db_driver();
host_name += m_dataset_info.m_dsn_name;
try
{
m_p_connection = m_p_sql_driver->connect(host_name.c_str(),
m_dataset_info.m_user_name.c_str(),
m_dataset_info.m_password.c_str());
}
catch (sql::SQLException &e)
{
/*
The MySQL Connector/C++ throws three different exceptions:
- sql::MethodNotImplementedException (derived from sql::SQLException)
- sql::InvalidArgumentException (derived from sql::SQLException)
- sql::SQLException (derived from std::runtime_error)
*/
wxString wx_text = wxT("# ERR: SQLException in ");
wx_text += wxT(__FILE__);
wxLogDebug(wx_text);
wx_text.Printf(wxT("# ERR: (%s) on line %d"),
__FUNCTION__,
__LINE__);
wxLogDebug(wx_text);
wx_text.Printf(wxT("# ERR: %s (MySQL error code: %d, SQLState: %s)"),
e.what(),
e.getErrorCode(),
e.getSQLState());
wxLogDebug(wx_text);
wxLogDebug(wxT("Verify that mysqlcppconn.dll is in the PATH or in the working directory."));
// throw Manager_Connection_Not_Initialized();
m_connection_initialized = false;
}
catch (...)
{
std::cout << "Unhandled database SQL exception\n" << flush;
m_connection_initialized = false;
}
m_connection_initialized = true;
}
return m_p_connection;
}
I am writing a multi-threaded application in C++ using Boost threads (pthread). The application spawns 100 threads and each thread does the following task (I am writing a code snippet that will be running in each thread):
try {
driver = get_driver_instance();
con = driver->connect(SettingsClass.HostName, \
SettingsClass.UserName,SettingsClass.Password);
// SettingsClass is a global static class whose members
// (HostName, UserName, Password, etc) are initialized once
// before *any* thread is created.
con->setSchema("MyDatabase");
driver->threadInit();
string dbQuery = "select A, B, C from XYZTable where D=?";
prepStmt = con->prepareStatement(dbQuery);
prepStmt->setInt(1, 1);
rSet = prepStmt->executeQuery();
/* Do Something With rSet, the result set */
delete rSet;
delete prepStmt;
if (con != NULL && !con->isClosed()) {
con -> close();
driver->threadEnd();
delete con;
}
catch (SQLException &e)
{
/* Log Exception */
}
On running the process (the app, as earlier mentioned, i.e. with 100 such threads), I attach gdb midway and observe that more than 40% of the threads have hanged in the read() call. All the backtraces have mysql library functions (vio_read(), etc) and none are from my code as my code does not perform any I/O.
Could anyone point out why is this issue arising. Should I check my code / network or MySQL server configuration? Have I used the C++ connector library properly?
I am getting runtime error on one of the machine. I have test my application on hundred of machine but not getting any kind of error. error window is shown below.
when crash the application shows error windows,
and if i click on clickhere link it shows below image.
and if I debug the code then it shows below image.
I don't know it is problem in my code or any problem in OS installation please help me. because my application runs everywhere and on all OS but getting error in only one of the computer.
code is given below:
rem->m_operationInProgress = false;
delete rem; // from where error occur.
printf("after deleted.."); //this is not execute.
and destructor is:
test::~test()
{
printf("\n Enter in destructor.. ");
//
// m_isRunning = false;
// Sleep(1000);
// //-------------------------------------------- 1_4_2012
// printf("\nCalling m_dataCollection->shutDown()");
//// printf("\n****calling m_connect.shutDown();****");
// printf("\nRPA :: 11....");
// m_connect.shutDown();
// printf("\nRPA :: 12....");
// //printf("\n****after m_connect.shutDown();****");
// printf("\nRPA :: 13....");
// if(m_device != NULL)
// {
// //printf("\n****before delete m_device;****");
// printf("\nRPA :: 14....");
// delete m_device;
// printf("\nRPA :: 15....");
// //printf("\n****after delete m_device;****");
// }
printf("\n Exited from destructor.. "); // this is also print on console.
}
it successfully execute both print f then crashed.
Can you tell us the difference between the machine you are testing on and the 'hundreds of machines' you have tested on? Your app seems to be multithreaded, and setting the operation-in-progress to false does not seem to immediately tell all threads to exit, especially if the computer under test is slow and single-core. So you probably prematurely deletes the pointer, while other threads are still using it. Hence the reason why the destructor is called, but then a slow thread wakes up somewhere and tries to use the pointer, that had long been deleted.
You probably need to add lock on the pointer to ensure that it is not deleted until all threads have exited.