Bug #91238 Not being able to use Connector/C++ in Debug mode
Submitted: 13 Jun 2018 13:27 Modified: 22 Jun 2018 5:43
Reporter: Milad Pro Email Updates:
Status: Not a Bug Impact on me:
None 
Category:Connector / C++ Severity:S3 (Non-critical)
Version: OS:Windows (10)
Assigned to: CPU Architecture:Other (Windows 10 64bit)
Tags: vs2015

[13 Jun 2018 13:27] Milad Pro
Description:
I'm using Windows 10 64bit and i wanted to use Connector/C++ in Visual Studio 2015.
As a senior developer I wanted to use MySQL in C++. From the documents of the website I found that the best way is to use Connector/C++ and JDBC. I was able to download it from the website and try it. I had no problem with using it in Release mode but I'm not able to use it in the Debug mode which is kind of a big problem. I tried the same code in both Release and Debug mode but in the Debug mode I get this error in Visual Studio 2015:
"Unhandled exception at 0x00007FFBE68A4008 in Project1.exe: Microsoft C++ exception: sql::SQLException at memory location 0x00000093818FECC0."
The error is generated after executing this line of code:
"boost::scoped_ptr< sql::Connection > con(driver->connect(host, user, pass));"
According to this section of the document (https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-apps-windows-visual-studio.ht...): "Because the application build configuration must match that of the Connector/C++ it uses, Release is required when using an Oracle-built Connector/C++, which is built in the release configuration. When linking dynamically, it is possible to build your code in debug mode even if the connector libraries are built in release mode. However, in that case, it will not be possible to step inside connector code during a debug session. To be able to do that, or to build in debug mode while linking statically to the connector, you must build Connector/C++ from source yourself using the Debug configuration.", It must be possible to use the .lib file in the debug mode. I both downloaded the library and build it myself from the source code (in both debug and release mode). But I couldn't use none of them in the Debug mode of my program. They give the same error.

How to repeat:
-
[13 Jun 2018 13:31] Milad Pro
I used mysqlcppconn.lib in my project (Dynamic).
[13 Jun 2018 14:15] MySQL Verification Team
Thank you for the bug report. Please attach here a C++ sample test case which presents the issue reported. Thanks.
[13 Jun 2018 14:22] Milad Pro
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <boost/scoped_ptr.hpp>
#include <jdbc/mysql_driver.h>
#include <jdbc/mysql_connection.h>
#include <jdbc/cppconn/build_config.h>
#include <jdbc/cppconn/config.h>
#include <jdbc/cppconn/connection.h>
#include <jdbc/cppconn/datatype.h>
#include <jdbc/cppconn/driver.h>
#include <jdbc/cppconn/exception.h>
#include <jdbc/cppconn/metadata.h>
#include <jdbc/cppconn/parameter_metadata.h>
#include <jdbc/cppconn/prepared_statement.h>
#include <jdbc/cppconn/resultset.h>
#include <jdbc/cppconn/resultset_metadata.h>
#include <jdbc/cppconn/sqlstring.h>
#include <jdbc/cppconn/statement.h>
#include <jdbc/cppconn/variant.h>
#include <jdbc/cppconn/version_info.h>
#include <jdbc/cppconn/warning.h>
#define EXAMPLE_DB   "testdb"
#define EXAMPLE_HOST "tcp://127.0.0.1:3305"
#define EXAMPLE_USER "root"
#define EXAMPLE_PASS "foo"
using namespace std;
using namespace sql;

int main(int argc, char *argv[])
{
	static const string host(argc >= 2 ? argv[1] : EXAMPLE_HOST);
	static const string user(argc >= 3 ? argv[2] : EXAMPLE_USER);
	static const string pass(argc >= 4 ? argv[3] : EXAMPLE_PASS);
	static const string database(argc >= 5 ? argv[4] : EXAMPLE_DB);
	size_t row;
	stringstream sql;
	stringstream msg;
	int i, affected_rows;
	sql::Driver * driver = sql::mysql::get_driver_instance();
	boost::scoped_ptr< sql::Connection > con(driver->connect(host, user, pass)); // Error in debug mode even when using the Debug mode made mysqlcppconn.lib. No error in release mode.
	boost::scoped_ptr< sql::Statement > stmt(con->createStatement());
}
[15 Jun 2018 11:29] Rafal Somla
It seems that the direct problem in your code is not catching the exception thrown by driver->connect(). This is what the error message says: "Unhandled exception at 0x00007FFBE68A4008 in Project1.exe: Microsoft C++ exception: sql::SQLException at memory location 0x00000093818FECC0.". If you add a catch() handler for this expection, you con print a nice error message instead of just "crashing" the app. See for example the jdbc_test.cc code in testapp/ folder of the source distribution.

After fixing above, your application should work, but note that if you want to build in Debug mode you need to build the connector in Debug mode first, as the builds we distribute are in Release mode. Using Release DLL with Debug code can lead to mysterious crashes due to different versions of the msvc runtime being used by both.

You seem to have already built Debug variant of Connector/C++, so you should be good. If needed, you can find information on how to build Connector/C++ here <https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-installation-source.html>.

Btw. The best way to use Connector/C++ is to grab version 8.0 and have a look at the new API - X DevAPI <https://dev.mysql.com/doc/connector-cpp/8.0/en/connector-cpp-introduction.html#connector-c...>.
[15 Jun 2018 12:34] Milad Pro
Thanks to Rafal Somla for suggesting a way to bypass the error.
But the real problem was that the parameters in driver->connect in debug mode must be of the type 'const char*' and unlike the release mode it's not possible to use std::string type. So it was possible to use this it in debug mode:
boost::scoped_ptr<sql::Connection> con(driver->connect(url.c_str(), user.c_str(), pass.c_str()));
But still, shouldn't both debug and release mode be the same?
And I got another error in debug mode in the following lines of my problem which I've pasted the code here:

...
boost::scoped_ptr<sql::Connection> con(driver->connect(url.c_str(), user.c_str(), pass.c_str()));
con->setSchema(database.c_str());
boost::scoped_ptr< sql::Statement > stmt(con->createStatement());
boost::scoped_ptr< sql::ResultSet >
      res(stmt->executeQuery("SELECT id, ch from t1"));

while (res->next())
{
    cout << res->getInt(1);
    cout << res->getString("ch") << endl; // ERROR in debug mode. getString works in release mode but not in debug mode.
}
...

And as Rafal Somla mentioned that the best way to use Connector/C++ is to grab version 8.0 and use X DevAPI, can't this be mentioned in the documentation? I chose JDBC because there was more tutorials for it and it seemed easier to work with.
This bug is for both the Connector/C++ and its documentation. The documentation is confusing to me.
[15 Jun 2018 16:21] Rafal Somla
Yes, a Debug build should work the same as Release build. So what you describe looks really strange to me (and I have not encountered this before). Smells to me like some sort of miss-match in compiler settings. I think MSVC compiler has switches about how to treat strings - maybe something is wrong there.
[21 Jun 2018 5:54] Milad Pro
About the last error in my code that I reported, I was able to fix it by using sql::SQLString.
This is the code:

// This works in both Debug and Release:
sql::SQLString var = res->getString("ch");
// var.c_str() can be helpful later.

// This only works in Release:
string var = res->getString("ch");
[22 Jun 2018 5:43] Chiranjeevi Battula
Hello Milad,

Thank you for your feedback.

Thanks,
Chiranjeevi.