Example programs crash on launch

By pbyhistorian on 2018-10-25 06:43:22 [link]

Weeks ago, I abandoned the Bakefile approach in favor of the MinGW makefile.  I was able to compile MySQL++ with the Windows distribution of MySQL Connector C 6.1.11 and the C++ Redistributable for Visual Studio 2015, but resetdb.exe crashed on launch with "resetdb has stopped working", followed by "The application was unable to start correctly (0xC0000005)".

So I decided to see if the Connector's test programs would work.  One has to compile from source to get those test programs.  I installed Visual Studio 2015 and then had to correct an error in the mysqlclient Project that CMake created: it failed to put quotes around paths containing spaces in the Librarian/All Options section.  After that, the Connector compiled and its test programs worked!

Next I headed back to MySQL++ with a fresh installation of Cygwin.  I copied MySQL++-3.2.4 into my home directory and ran the MinGW makefile - same crash using the Connector C libs I'd just built.  Hoping the Windows dist of Connector C would work with a properly-installed Visual Studio, I ran the makefile again against original the libs - same crash.

Any help would be appreciated.

By tangent on 2018-10-25 07:20:34 [link]

You must distinguish MinGW from Cygwin. Be certain you're not trying to mix the build types! One way to do that is to get Cygwin out of the picture entirely.

(I'm not anti-Cygwin. In fact, I greatly prefer it to MinGW. But that's a side issue to the one at hand, which is that you can't mix the two unless you're uncommonly knowledgeable about the two toolchains.)

One of the problems with "MinGW" is that there are something like 3 or 4 major flavors of it floating around: the original code line, "mingw64", the MinGW toolchain shipping with Cygwin, the MinGW toolchain for non-Windows platforms... Which one do you mean? Give a URL.

Assuming you do in fact have a pure MinGW build, I'd run the program in a debugger to find out where it's crashing. Windows error 0xC0000005 is extremely vague: it's like a segfault on a POSIX platform. You must debug it to find out what it means.

By pbyhistorian on 2018-10-30 05:40:52 and edited on 2018-10-31 08:48:16 [link]

I remembered I wasn't supposed to use Cygwin so I completely erased it from my computer.  (It's easy to re-install, should I ever need it.)  So I'm certain I'm not mixing the build types.

My MinGW (32-bit) is from the original MinGW (not MinGW64) website.  The code was maintained by another purist, Keith Marshall, when I last downloaded (2016).  To-date, all of my projects have been pure Win32: I don't use Boost or JQuery, .NET, COM, C++ redistributables, etc.  I've also avoided DLLs (except Win32), preferring static libraries to avoid Microsoft's "DLL hell".  I keep my MinGW as pure as I can possibly make it.

To follow your recommendation, I'm going to try to debug MySQL++ as an Eclipse makefile Project.  Running mingw32-make -f Makefile.mingw seems to have found two problems so far:
1) On line 369, the makefile appears to be trying to link "mysqlpp_ssqls2parse".  The closest I can find to that is the rule just prior, which creates "libmysqlpp_ssqls2parse.a".  Substituting the latter for the former doesn't correct the failure.  Was Bakefile supposed to create "libmysqlpp_ssql2parse.lib" instead?
2) On line 405, there's more confusion about linking that same file.


By wyetr on 2018-10-31 18:35:22 [link]

I've made some improvements to the build system for stock 32-bit standalone MinGW with the 32-bit version of MySQL Connector/C 6.1.

Anticipating that you're probably not interested in cloning our Fossil repository and re-generating Makefile.mingw from the mysql++.bkl file, I've uploaded a version I just generated here.

The generated version assumes you've got Connector/C installed in C:\Program Files\MySQL\MySQL Connector C 6.1. If you're on a 64-bit OS but are using 32-bit MinGW and 32-bit Connector/C, it will be under C:\Program Files (x86) instead, and you'll have to adjust the paths by replacing all the instances of it in Makefile.mingw or changing the single instance in mysql++.bkl and re-baking it per the instructions in

These fixes will appear in the next release, but I currently have no concrete plans for making another release.

By pbyhistorian on 2018-11-11 19:04:56 and edited on 2018-11-11 19:17:19 [link]

Thanks for the new makefile. I replaced all occurrences of the default path with that of the working build of Connector C I made with VS 2015. Unfortunately resetdb.exe still fails in the same way.

I'm not an expert with gbd, but the very first thing resetdb.exe does is call MySQL++::get_library_version() and this is where the crash immediately occurs. From what I (in ignorance) can tell, the call to that function jumps to un-initialized memory.

So I returned to Eclipse and referred to the makefile output for the appropriate compiler and linker settings. I was then able to reach get_library_version() (hooray!), where I'd previously commented-out its call to the Connector C library and replaced it with a single cout and return 0. When I returned that code to original, the linker complained massively about undefined references. Adding --enable-stdcall-fixup and --enable-runtime-pseudo-reloc resolved all but one, so I think I'm close to success.

However, would adding extern C {<various Connector C functions>} to MySQL++ be a better approach?

That brings me to linking. I desperately want to avoid DLLs and both Connector C and MySQL++ produce static libraries. (The more self-contained a program is, the less likely it will experience external problems down the road, IMO.)

Am I correct in thinking I can statically link both libraries to create resetdb.exe?

Finally, libmysql.lib (static Connector C library) is quite small, making me think it's just some kind of wrapper for the Connector C DLL. But according to nm, mysqlclient.lib (static Connector C library) appears to contain real code.

Can I use mysqlclient.lib to successfully create resetdb.exe (and others)?

"I currently have no concrete plans for making another release"
Thanks for all the work you've done on our behalf!

By tangent on 2018-11-11 20:10:17 [link]

resetdb.exe still fails in the same way.

The new makefile was tested by using it to build the examples, which then ran successfully, so your build problems are now all local. MySQL++ itself works.

would adding extern a better approach

The MySQL/MariaDB C API headers already wrap their own declarations in extern "C", which you can see by inspecting their header files.

I desperately want to avoid DLLs and both Connector C and MySQL++ produce static libraries.

That means you either cannot distribute the resulting binaries or you must do so under the terms of the GPL. Since these risks you're worried about pretty much only come up when distributing the programs to others, are you willing to put your own code under the GPL?

Am I correct in thinking I can statically link both libraries to create resetdb.exe?

In principle, sure, but since I never do that, you're on your own to work out how to achieve it.

All-static builds make very little sense to me. That's a return to primitive methods, IMHO. Except in very special circumstances, I don't see enough compensating value to make me want to throw away all the benefits we've bought with dynamic linkage techniques, which I've personally seen in programs as old as about 1970.

Recreating history for its own sake has value, but for new development with modern libraries and tools? That makes as much sense to me as punching a hole in the living room ceiling and setting a fire pit in the center because that's simpler than central heating.

The more self-contained a program is, the less likely it will experience external problems down the road, IMO.

What's the cost of all the self-inflicted problems you're dealing with right now?

The only case in which you won't have any more problems down the road is if you never upgrade the C API library or MySQL++ again. If you do, you've got to rebuild the whole program again, but this time under an OS, IDE, compiler, and standard library stack that's likely to have changed in the meantime, so now you've got to work out any problems resulting from those changes.

Contrast "install the new DLL and restart the program."

libmysql.lib (static Connector C library) is quite small, making me think it's just some kind of wrapper for the Connector C DLL.

Yes, it's called an import library. All it does is glue your program to the DLL.

Can I use mysqlclient.lib to successfully create resetdb.exe (and others)?

This is part of what I referred to above.

But, realize that I've already gone far out of my way to get you this far. I don't use MySQL++ on Windows, I don't do static builds, and I don't use Eclipse, so you're at least 3 degrees separated from my area of expertise.

By tangent on 2018-11-11 20:21:12 [link]

At least four degrees: as far as I recall, I've only ever used MinGW to answer questions like yours. I don't recall ever using MinGW for any purely personal purpose.

Another thought: if a return to simpler methods is so valuable, why use Eclipse and C++ at all? I'd think you'd be happier with Connector/C, hand-written Makefiles, and a plain text editor. I'm not being facetious: my daily work is closer to that than the build system you're working with.

Indeed, why use MySQL? Talk about complexity and dependence. Have you considered using SQLite instead?

By pbyhistorian on 2018-11-12 01:37:12 and edited on 2018-11-12 01:43:02 [link]

Thanks for answering my questions.

This library will be purely for my own home use so I should be OK with the GPL license.

My goal is always to write code and spend no more time stack-tending than absolutely necessary.

I'm going to try to get MySQL++ working with Eclipse, MinGW, and static libraries (optional) because I like MySQL, C++, and Eclipse, and I think other Windows users do too. However, the authors of MySQL, MySQL++, and MariaDB mostly live in the *nix world and they themselves point out how difficult it is to get their code running under Windows due to DLLs. So it seems there's not a lot of support for Windows users even though we may outnumber the *nix base. You've made an effort (thank you) but that last reply definitely became facetious.

You're right about Makefiles though; I would certainly write my own (if they didn't hide errors that IDEs make us fix) with too much documentation - and ditch Bakefile altogether.

By pbyhistorian on 2018-11-12 09:14:29 [link]

resetdb is now working, even though I'm still linking to the static MySQL++ library and the Connector C DLL. The difference is that I got Eclipse to drive MinGW instead of letting mingw32-make do it.

I'm mildly surprised that mingw32-make didn't work because I got the build parameters (for Eclipse) straight from its output.