Fixing spatialite loading problem

A few days ago, I’ve got an issue with spatialite - mod_spatialite-4.3.0a-win-amd64. After googling for a solution, I found some people with the very same issue and no solution.
Then, I decided to try to figure it out.

Symptoms

I was developing a tool to work with spatial data and when I tried to use spatialite from a C# application I got the following error:

1
Unhandled Exception: SQLite.SQLiteException: A dynamic link library (DLL) initialization routine failed.

Debugging

Testing SQLite wrapper

My first approach was to replace System.Data.SQLite Version 1.0.99 SQLite 3.9.2. Since it has a custom interop assembly (SQLite.Interop.dll), I thought it could be something regarding the way it was compiled.

I’ve then tried to load mod_spatialite using sqlite-net. No lucky.
I’ve even used libsqlite3-0 shipped with mod_spatialite-4.3.0a-win-amd64 to be sure to be running correct versions. I’ve got the same error.

Testing mod_spatialite

Since I got two different paths leading to the very same problem, I guessed it was something to do with mod_spatialite it self.
I’ve download mod_spatialite-4.3.0a-win-amd64 and tested it using the bundled sqlite3.exe.

It was able to load mod_spatialite without any problems.

Digging depper with WinDBG

Since everything was working perfecly when separated, I’ve decided to dig deeper with WinDBG.
Then, I got an Access violation - code c0000005 after issuing trying to load mod_spatialite with the command below.

1
SELECT load_extension('mod_spatialite')

Below is call stack when the error occurred. Looks like something went wrong during libstdc++_64-6.dll.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# RetAddr : Args to Child : Call Site
00 00000000`6a5d9c29 : 00000203`b5b80000 0000007d`50000061 0000007d`069fd718 00000000`6a647a00 : libstdc___64_6!_cxa_demangle+0x12610
01 00000000`6a5da052 : 00000000`6a648014 00000000`6a647a00 00000000`6a648014 00000000`00000000 : libstdc___64_6!_cxa_demangle+0xc3a9
02 00000000`6a6475ce : 00000000`00000000 00000000`6a5c117a 00000000`6a6894e0 00007ffd`dd0bb7b0 : libstdc___64_6!_cxa_demangle+0xc7d2
03 00000000`6a5cdf75 : 00000000`00000001 00000000`00000001 00000000`6a5c13e0 00000000`6a648014 : libstdc___64_6!atomic_flag_test_and_set_explicit+0x26e
04 00000000`6a5c137a : 00000000`00000001 00007ffd`dd9a52c8 00000000`00000001 00000000`6a5dc090 : libstdc___64_6!_cxa_demangle+0x6f5
05 00007ffd`dd9a52c8 : 00000000`00000000 00000000`00000001 0000007d`069fdb74 00007ffd`dda021a6 : libstdc___64_6+0x137a
06 00007ffd`dda020ca : 00000203`b5b948a0 00000000`6a5c0000 00000000`00000001 00000203`b5b94f30 : ntdll!LdrpCallInitRoutine+0x4c
07 00007ffd`dda01f0f : 00000203`b5b949f0 00000203`b5b94900 0000007d`069fd9b0 00000000`6a5c13e0 : ntdll!LdrpInitializeNode+0x162
08 00007ffd`dda01f2d : 00000000`00000000 00000203`b5b942d0 0000007d`069fd9f0 00000000`00000020 : ntdll!LdrpInitializeGraphRecurse+0x73
09 00007ffd`dda01f2d : 00000203`b5b91400 00000203`b5b94150 0000007d`069fda30 00000000`69a813e0 : ntdll!LdrpInitializeGraphRecurse+0x91
0a 00007ffd`dda01f2d : 0000007d`069fdc00 00000203`b59d4e70 0000007d`069fda70 00000203`00000000 : ntdll!LdrpInitializeGraphRecurse+0x91
0b 00007ffd`dd99bb85 : 00000000`00000000 00000000`00000000 0000007d`069fdac0 0000007d`069fdb74 : ntdll!LdrpInitializeGraphRecurse+0x91
0c 00007ffd`dd9a1ed4 : 0000007d`069fdb74 00000000`00000000 00000000`00000000 0000007d`069fdb80 : ntdll!LdrpPrepareModuleForExecution+0xc5
0d 00007ffd`dd9a19fe : 0000007d`069fdb80 0000007d`069fdd10 00000000`00000000 00000000`00000001 : ntdll!LdrpLoadDllInternal+0x1a8
0e 00007ffd`dd9a0c44 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000001 : ntdll!LdrpLoadDll+0xf2
0f 00007ffd`da82c77f : 00000203`b5b84e18 00007ffd`0000000f 0000000f`00000001 00000203`b5b84e18 : ntdll!LdrLoadDll+0x114
10 00000000`663908e9 : 00000203`00000000 00000203`b75258e8 00000203`b57efb25 00000000`00000000 : KERNELBASE!LoadLibraryExW+0x16f
11 00000000`66384952 : 00000000`66448f40 00000203`cfbdf588 00000203`b59d4e70 00000000`00000001 : sqlite3!sqlite3_win32_set_directory+0x3cba
12 00000000`663eee51 : 00000000`66448f40 00000203`cfbdf588 00000203`b57efb25 0000007d`069fe0c8 : sqlite3!sqlite3_db_status+0x312f
13 00000000`663ef331 : 00000203`b5b847a8 00000203`cfbdf588 00000000`00000000 0000007d`069fdfb0 : sqlite3!sqlite3_exec+0x4b9
14 00000000`663e6fa0 : 00000203`b5b847a8 00000203`cfbdf588 00000000`00000000 0000007d`069fdfb0 : sqlite3!sqlite3_load_extension+0x46
15 00000000`663bc0fa : 00000203`cfbdf408 00000000`00000001 00000203`cfbdf438 00000203`b5b94140 : sqlite3!sqlite3_strglob+0x11d0
16 00000000`663b7f69 : 00000203`cfbe0798 00000000`663851b6 00000203`b5b81db8 0000007d`069fea30 : sqlite3!sqlite3_value_numeric_type+0x1eb8
17 00000000`663b811e : 00000203`cfbe0798 00000203`b75258e8 00140203`b5913950 00000000`00000000 : sqlite3!sqlite3_result_error_nomem+0x2e9
18 00007ffd`5c184244 : 00000203`cfbe0798 00000203`b75258e8 0000007d`069feba0 00000203`b75258e8 : sqlite3!sqlite3_step+0xd2
19 00007ffd`5c1837a8 : 00000203`cfbe0798 00007ffd`5c1e1420 00000203`cfbdfab0 00000203`b5b87101 : 0x00007ffd`5c184244
1a 00007ffd`5c182de6 : 00000203`b75258e8 00000203`b7525360 00000203`b59269b8 00000000`00000000 : 0x00007ffd`5c1837a8
1b 00007ffd`5c181657 : 00000203`b7525640 00000203`b7525360 00000203`b7525868 00007ffd`ba8a8bc0 : 0x00007ffd`5c182de6
1c 00007ffd`bb7c3bd3 : 00000203`b7524508 00007ffd`5c0640c0 00000000`00000000 00000000`00000000 : 0x00007ffd`5c181657
1d 00007ffd`bb7c3a95 : 0000007d`069ff038 00007ffd`bb8fe619 00000000`00000000 00000000`00000000 : clr!CallDescrWorkerInternal+0x83
1e 00007ffd`bb7c44c6 : 00000000`00000001 0000007d`069fefb0 0000007d`069fef80 0000007d`069feef8 : clr!CallDescrWorkerWithHandler+0x4e
1f 00007ffd`bb8bb710 : 0000007d`069fee80 00000000`00000000 00000000`00000000 00000000`00000001 : clr!MethodDescCallSite::CallTargetWorker+0xf8
20 00007ffd`bb8bb8aa : 00000000`00000001 00000000`00000000 00000203`00000000 00000203`b7524508 : clr!RunMain+0x1e7
21 00007ffd`bb8bb7a0 : 00000000`00000000 00000203`b7521628 00000000`00000000 00000203`b59cda80 : clr!Assembly::ExecuteMainMethod+0xb6
22 00007ffd`bb8bba13 : 0000007d`069ff9f8 00000203`b57e0000 00000000`00000000 00000000`00000000 : clr!SystemDomain::ExecuteMainMethod+0x5ea
23 00007ffd`bb8bb9ea : 00000203`b57e0000 00000000`00000000 00000000`00000000 00007ffd`bd254a38 : clr!ExecuteEXE+0x3f
24 00007ffd`bb8cdea0 : ffffffff`ffffffff 00000000`00000000 0000007d`06464000 00000000`00000000 : clr!_CorExeMainInternal+0xb2
25 00007ffd`bd1f802d : 00000000`00000000 00000000`00000091 00000000`00000000 0000007d`069ffab8 : clr!CorExeMain+0x14
26 00007ffd`bd291184 : 00007ffd`bd2910a0 00007ffd`bb8cde8c 00000000`00000000 00007ffd`bd1f7fd0 : mscoreei!CorExeMain+0xe0
27 00007ffd`bd2910ab : 00007ffd`bd1f0000 00007ffd`bd2910a0 00000000`00000000 00000000`00000000 : MSCOREE!ShellShim__CorExeMain+0xb8
28 00007ffd`dd0b8102 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : MSCOREE!CorExeMain_Exported+0xb
29 00007ffd`dd9ec5b4 : 00007ffd`dd0b80e0 00000000`00000000 00000000`00000000 00000000`00000000 : KERNEL32!BaseThreadInitThunk+0x22
2a 00000000`00000000 : 00000000`00000000 00000000`00000000 00000000`00000000 00000000`00000000 : ntdll!RtlUserThreadStart+0x34

Isolationg the problem

Well, libstdc++_64-6.dll has nothing to do with spatialite it self, it’s just a dependency.
To be sure it was something with lib initialization I’ve tried to load it manually with the code below. As expected it failed.

1
2
3
4
5
6
7
8
9
public class Program {
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Ansi)]
static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName);
public static void Main(string[] args) {
var intPtr = LoadLibrary("libstdc++_64-6.dll");
}
}

Digging into libstdc++-6.dll

libstdc++-6.dll is part of MinGW-W64. Since the DLL hasn’t any information regarding it’s version I’ve then download the latest MinGW-W64 x86_64-5.3.0-win32-seh-rt_v4-rev0.
The downloaded version of libstdc++-6.dll loaded perfectly fine using LoadLibrary("libstdc++-6.dll");

Updating libstdc++-6.dll

libstdc++-6.dll has a dependency to libgcc_s_seh-1.dll. So, both DLLs should be updated.
Since mod_spatialite.dll is looking from libstdc++_64-6.dll instead of libstdc++-6.dll you have to rename it to the correct name.
As the new libstdc++-6.dll is looking for libgcc_s_seh-1.dll instead of libgcc_s_seh_64-1.dll, you can delete libgcc_s_seh_64-1.dll shipped mod_spatialite-4.3.0a-win-amd64 and just copy libgcc_s_seh-1.dll.

Conclusion

After upgrading libstdc++-6.dll everything worked as expected. I’ve tested it against the following scenario:

  • Windows 10 x64 - [Version 10.0.10586]
  • .NET Framework v 4.6.1
  • System.Data.SQLite Version 1.0.99 [SQLite 3.9.2]
  • mod_spatialite-4.3.0a-win-amd64.

I’ve also posted to spatialite-users mailist this workaround.
As Sandro Furieri pointed out, it may be not safe to just replace core DLLs in this way because the ABI might have changed. I’ve been using this workaround without any issues so far.

I hope this module gets compiled with a newer version of MinGW-W64 in the next release.