Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault when using mysql on Windows #18

Open
pavonia opened this issue Sep 30, 2015 · 3 comments
Open

Segmentation fault when using mysql on Windows #18

pavonia opened this issue Sep 30, 2015 · 3 comments

Comments

@pavonia
Copy link

pavonia commented Sep 30, 2015

I'm trying to use mysql-0.1.1.8 on a Windows system. I managed to circumvent #3 by passing the flags manually via --extra-include/lib-dirs to cabal. However, there are more problems because pthread is not supported on Windows systems. Using pthreads-win32 (http://www.sourceware.org/pthreads-win32/) still leads to errors because several definitions from signal.h are not found in my MinGW installation.

As all the pthread functions only seem to be used to avoid RTS interruptions, I removed mysql_signals.h and mysql_signals.c from the project and changed the foreign import calls in Database.MySQL.Base.C back to their original names, e.g.

foreign import ccall unsafe "mysql_signals.h _hs_mysql_real_connect"

becomes

foreign import ccall unsafe mysql_real_connect

etc.

After doing these changes the package builds fine, the following test program builds fine and there aren't any linker errors anymore.

module Main where

import Control.Exception
import Database.MySQL.Base

main :: IO ()
main = do
    putStrLn $ "Client info: " ++ clientInfo
    handle (\e -> putStrLn $ "ERROR: " ++ show (e :: MySQLError)) $ do
        conn <- connect $ ConnectInfo {
                connectHost = "localhost",
                connectUser = "root",
                connectPassword = "pass",
                connectDatabase = "",
                connectPort = 0,
                connectOptions = [],
                connectPath = "",
                connectSSL = Nothing
            }
        info <- serverInfo conn
        putStrLn $ "Server info: " ++ info
        close conn

The only problem is the program produces a segmentation fault when run:

Client info: 5.0.51a
Segmentation fault/access violation in generated code

Note that the call to clientInfo works fine, but the attempt to connect to the database segfaults. I thought it might be an incompatible MySQL version of something like that, so I wrote a small C program doing basically the same function calls, and that works fine:

#include <stdio.h>
#include <stdlib.h>
#include <winsock.h>
#include <mysql.h>

int main(int argc, char **argv)
{  
    MYSQL *conn = mysql_init(NULL);

    if (conn == NULL) {
        printf("%s\n", mysql_error(conn));
        exit(1);
    }

    printf("Client info: %s\n", mysql_get_client_info());

    if (mysql_real_connect(conn, "localhost", "root", "pass", NULL, 0, NULL, 0) == NULL) {
        printf("%s\n", mysql_error(conn));
        mysql_close(conn);
        exit(1);
    }

    printf("Server info: %s\n", mysql_get_server_info(conn));

    mysql_close(conn);
    exit(0);
}

outputs

Client info: 5.0.51a
Server info: 5.1.32-community

Performing SQL requests and fetching the result also works fine in C. So the problem clearly is related to the Haskell package, but I have no idea where to start debugging this. May it be the changes I did to the package causing this problem? I would try using the functions from Database.MySQL.Base.C directly but I'm not familiar with the FFI, so I don't know how to use them safely.

Any ideas on that?

@pavonia
Copy link
Author

pavonia commented Oct 1, 2015

Finally, I've managed to get mysql to work. Maybe someone had similar trouble, so here's an explanation of what I did:

  • Remove all references to mysql_signals.h and mysql_signals.c from the cabal file. These files won't be used for compilation.

  • In the cabal file, add extra-libraries: libmysql to the library section.

  • In modules Database\MySQL\Base\C.hsc and Database\MySQL\Base\Types.hsc add

    #include <winsock.h>
    

    before the include of mysql.h.

  • Also in module Database\MySQL\Base\C.hsc, replace all foreign imports from mysql_signals.h by their original function name, i.e. remove the quoted part from the import declaration. While doing that, also replace the call method from ccall to stdcall. Note that this needs to be done for all imports while renaming the import has to be done only for the functions redefined via mysql_signals.h. As an example, the line

    foreign import ccall unsafe "mysql_signals.h _hs_mysql_real_connect" mysql_real_connect
    

    becomes

    foreign import stdcall unsafe mysql_real_connect
    
  • Find a way to circumvent mysql_config not found on windows #3. What I did was replacing Setup.lhs with a simple setup file:

    > import Distribution.Simple
    > main = defaultMain
    

    This requires you to pass the include and lib options yield by mysql_config to cabal manually.

  • Configure cabal with the paths to the mysql header and lib files.

    cabal configure --extra-include-dirs=<path-to-mysql>/include --extra-lib-dirs=<path-to-mysql>/lib/opt --ld-options="-L<path-to-mysql>/lib/opt -llibmysql"
    
  • Build the package as usual (cabal build; cabal install). You shouldn't get any compilation or linker error here anymore.

After that, the example from my previous comment should also compile and link fine, and running it shouldn't yield a segmenation fault anymore. Running the program from GHCi should also work.

I'm aware that this is a terrible hack and some MySQL features may not work correctly (or at all), and there still is the risk of GHC's RTS interfering with the SQL connection requests. But for me the basic functions for sending requests and fetching data work fine, so I don't really care at the moment.

Any comments or suggestions of a more sane way to build the package on Windows are welcome, of course.

@3noch
Copy link

3noch commented Oct 1, 2015

Thanks for documenting this. Are you building for 64-bit?

@pavonia
Copy link
Author

pavonia commented Oct 1, 2015

No, I'm using an older 32-bit Windows XP system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants