c++ mysql sqlstring crashes 0xC0000005 unable to read memory

0

I've been looking for this error in several places and the only thing I found is maybe is a wild pointer problem, but don't know how to solve.

The question is c++ connector works fine (after hard working) connects to mysql database, retrieves information, but every time that uses string or sqlstring type it crashes, (so I can't get the info from the recordset) with same error:

Not controlled exception at 0x5e477a8b (msvcp90d.dll) access violation when reading memory position at 0x00445355.

Here the code I'm using:

int main() {

    Driver *driver;
    Connection *con;
    Statement *stmt;
    ResultSet *res;
    string fld;
    char *fldName = "divisa";

    int row=1, nrows=0;
    char *url, *database, *usr, *pw;

    url = DBHOST;
    database = DATABASE;
    usr = getstr("User: ", -1, 128); // char* getstr(char prompt[], char chReplace, int maxLen);
    pw = new char[128];
    pw = getstr("Password: ", '\0', 128);
    cout << endl;

    try {
        driver = get_driver_instance();
        con = driver->connect(url, usr, pw);
        pw = new char[128];
        con->setAutoCommit(0);
        con->setSchema(database);
        stmt = con->createStatement();

        res = stmt->executeQuery("SELECT * FROM `estglob`");

        while(res->next()) {    
            fld.assign(res->getString(fldName));
            cout << fld << endl;
        }

        _getch();
        cout << endl << "Cleaning up the resources .." << endl;

        delete res;
        delete stmt;
        con -> close();
        delete con;
    }
    catch (SQLException &e) {
        cout << endl << "ERROR: SQLException in " << __FILE__;
        cout << " (" << __FUNCTION__<< ") on line " << __LINE__ << endl;
        cout << "ERROR: " << e.what();
        cout << " (MySQL error code: " << e.getErrorCode() << ")";
        cout << ", SQLState: " << e.getSQLState() << ")" << endl; // <== CRASH here

        _getch();
        return(EXIT_FAILURE);
    }
    catch (std::runtime_error &e)
    {
        cout << "ERROR: runtime_error in " << __FILE__;
        cout << " (" << __FUNCTION__ << ") on line " << __LINE__ << endl;
        cout << "ERROR: " << e.what() << endl;

        _getch();
        return(EXIT_FAILURE);
    }

    return(EXIT_SUCCESS);
}

Any suggestion / comments will be really well recieved!


So here the callstack at error point:

msvcr90d.dll!memcpy(unsigned char * dst=0x0031fa14, unsigned char * src=0x00445355, unsigned long count=0x0000000f) Línea 314 Asm

msvcr90d.dll!memcpy_s(void * dst=0x0031fa14, unsigned int sizeInBytes=0x0000000f, const void * src=0x00445355, unsigned int count=0x0000000f) Línea 67 + 0x11 bytes C

msvcp90d.dll!std::char_traits::_Copy_s(char * _First1=0x0031fa14, unsigned int _Size_in_bytes=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f) Línea 582 + 0x16 bytes C++

msvcp90d.dll!std::_Traits_helper::copy_s >(char * _First1=0x0031fa14, unsigned int _Size=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f, std::_Secure_char_traits_tag __formal={...}) Línea 714 + 0x15 bytes C++

msvcp90d.dll!std::_Traits_helper::copy_s >(char * _First1=0x0031fa14, unsigned int _Size=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f) Línea 706 + 0x22 bytes C++

msvcp90d.dll!std::basic_string,std::allocator >::assign(const std::basic_string,std::allocator > & _Right= erróneo, unsigned int _Roff=0x00000000, unsigned int _Count=0xffffffff) Línea 1067 + 0x25 bytes C++

msvcp90d.dll!std::basic_string,std::allocator >::assign(const std::basic_string,std::allocator > & _Right= erróneo) Línea 1052 C++

testMySQL.exe!wmain(int argc=0x00000001, wchar_t * * argv=0x00834a30) Línea 61 + 0x8d bytes C++

testMySQL.exe!__tmainCRTStartup() Línea 579 + 0x19 bytes C

testMySQL.exe!wmainCRTStartup() Línea 399 C

kernel32.dll!77391194()

[Los marcos siguientes pueden no ser correctos o faltar, no se han cargado símbolos para kernel32.dll]
ntdll.dll!77c7b495()
ntdll.dll!77c7b468()

c++
mysql
string
asked on Stack Overflow Nov 19, 2010 by Miquel • edited Oct 7, 2016 by Miquel

6 Answers

1

I am assuming you are using MySql Connector/C++ here.

Not sure if this is the problem, but typically result iteration looks like this:

res = stmt->executeQuery("SELECT * FROM `estglob`");
while (res->next()) 
{
  cout << "id = " << res->getString(1);
}

Are you sure the first column in your result set contains string data? Your logic would be more reliable using the column name instead of its index.

  cout << "id = " << res->getString("nameOfColumnWithStringData");

Another possibility is that if you are using the binary MySql Connector/C++ libraries, you are using a different Visual Studio than what they were built with. You could try building the MySql libs from source using the same VS as your app is built with, if that's the case. Check this using depends.exe on the MySql DLLs and on your EXE - if they reference different MSVC*.DLL versions, that's a potential problem.

answered on Stack Overflow Nov 19, 2010 by Steve Townsend
1
usr = getstr((char*)"User: ", -1, 128);
pw = new char[128];
pw = getstr((char *)"Password: ", '\0', 128);

I don't know what getstr does, but casting a string literal to a char* is an immediate sign that you're going to do something very, very, wrong. Use a std::string and the c_str() member function instead. I'm also looking at your plethora of deletes and feeling the potential for bad news right there - you should use a scoped pointer to control the memory, as you're begging for leaks.

answered on Stack Overflow Nov 19, 2010 by Puppy
1

Building on Steve Townsend's answer perhaps your loop is your issue.

The following is a good loop example because next() gets called immediately moving the internal cursor to the first item and populating it.

res = stmt->executeQuery("SELECT * FROM `estglob`");
while (res->next()) 
{
    cout << "id = " << res->getString(1);
}

In your code you are calling first() without then calling next() internally I believe the first() function moves the cursor to before the start and the first call to next() moves the internal cursor to the first item.

answered on Stack Overflow Nov 19, 2010 by Dean Taylor
0

The new code is here:

Driver *driver;
Connection *con;
Statement *stmt;
ResultSet *res;
string fld;
char *fldName = "divisa";

int i;
char *url, *database, *usr, *pw;

url = (char *) calloc(256, sizeof(char));
database = (char *) calloc(64, sizeof(char));
usr = (char *) calloc(64, sizeof(char));
pw = (char *) calloc(64, sizeof(char));

url = DBHOST;
database = DATABASE;
usr = getstr("User: ", -1, 64); // Get user home made function
pw = getstr("Password: ", '\0', 64); // Get password home made function
cout << endl;

try {
    driver = get_driver_instance();
    con = driver->connect(url, usr, pw); // create a database connection using the Driver
    for (i=0; i<64; i++) pw[i] = '\0';

    con->setAutoCommit(0); // turn off the autocommit
    con->setSchema(database); // select appropriate database schema
    stmt = con->createStatement(); // create a statement object

    res = stmt->executeQuery("SELECT * FROM `estglob`");

    while(res->next()) {    
        fld.assign(res->getString(fldName));
        cout << fld;
    }

    _getch();
    cout << endl << "Cleaning up the resources .." << endl;

    // Clean up
    con -> close();
    free(res);
    free(driver);
    free(con);
    free(stmt);
}
catch (SQLException &e) {
    cout << endl << "ERROR: SQLException in " << __FILE__;
    cout << " (" << __FUNCTION__<< ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what();
    cout << " (MySQL error code: " << e.getErrorCode() << ")";
    //cout << ", SQLState: " << e.getSQLState() << ")" << endl;

    if (e.getErrorCode() == 1047)
    {
        //
        // Error: 1047 SQLSTATE: 08S01 (ER_UNKNOWN_COM_ERROR)
        // Message: Unknown command

        cout << "\nYour server does not seem to support Prepared Statements at all. ";
        cout << "Perhaps MYSQL < 4.1?" << endl;
    }

    _getch();
    return(EXIT_FAILURE);
}
catch (std::runtime_error &e)
{
    cout << "ERROR: runtime_error in " << __FILE__;
    cout << " (" << __FUNCTION__ << ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what() << endl;

    _getch();
    return(EXIT_FAILURE);
}

return(EXIT_SUCCESS);

And here the callstack at error point:

msvcr90d.dll!memcpy(unsigned char * dst=0x002bf794, unsigned char * src=0x00445355, unsigned long count=0x0000000f) Línea 314 Asm

msvcr90d.dll!memcpy_s(void * dst=0x002bf794, unsigned int sizeInBytes=0x0000000f, const void * src=0x00445355, unsigned int count=0x0000000f) Línea 67 + 0x11 bytes C

msvcp90d.dll!std::char_traits::_Copy_s(char * _First1=0x002bf794, unsigned int _Size_in_bytes=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f) Línea 582 + 0x16 bytes C++

msvcp90d.dll!std::_Traits_helper::copy_s >(char * _First1=0x002bf794, unsigned int _Size=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f, std::_Secure_char_traits_tag __formal={...}) Línea 714 + 0x15 bytes C++

msvcp90d.dll!std::_Traits_helper::copy_s >(char * _First1=0x002bf794, unsigned int _Size=0x0000000f, const char * _First2=0x00445355, unsigned int _Count=0x0000000f) Línea 706 + 0x22 bytes C++

msvcp90d.dll!std::basic_string,std::allocator >::assign(const std::basic_string,std::allocator > & _Right= erróneo, unsigned int _Roff=0x00000000, unsigned int _Count=0xffffffff) Línea 1067 + 0x25 bytes C++

msvcp90d.dll!std::basic_string,std::allocator >::assign(const std::basic_string,std::allocator > & _Right= erróneo) Línea 1052 C++

testMySQL.exe!wmain(int argc=0x00000001, wchar_t * * argv=0x008d4a30) Línea 65 + 0x8d bytes C++ testMySQL.exe!__tmainCRTStartup() Línea 579 + 0x19 bytes C testMySQL.exe!wmainCRTStartup() Línea 399 C kernel32.dll!77391194()

[Los marcos siguientes pueden no ser correctos o faltar, no se han cargado símbolos para kernel32.dll]
ntdll.dll!77c7b495()
ntdll.dll!77c7b468()

answered on Stack Overflow Nov 19, 2010 by Miquel
0

Change fld.assign(res->getString(fldName)); to fld = res->getString(fldName);

0

You are not alone,
this is a recent problem in Teeworlds ddrace mod too. And as I googled I saw many others have the same problem (just google for: getString mysql windows).
It basically happens when getString accesses a value of a column with varchar's longer than 15 chars and if you use a different compiler for your app than they used for compiling the mysql cpp connector also you need to choose the right (/same) compiler settings (/MD, /MDd, /MT, /MTd). There are f.e. mysql cpp 1.0.5 connectors build with VC90.CRT and others build with VC80.CRT. You can read about this stuff here...
Why do I need to know?
CAUTION: binary compatibility on Windows

Found this information at:
http://bugs.mysql.com/bug.php?id=56742

answered on Stack Overflow Feb 28, 2011 by Allisone • edited Mar 1, 2011 by Allisone

User contributions licensed under CC BY-SA 3.0