Skip to content

lib/gis: Fix "Implicit conversion loses precision" warnings - #7947

Merged
nilason merged 4 commits into
OSGeo:mainfrom
nilason:fix_libgis_implicit_conversion
Oct 3, 2026
Merged

nilason merged 4 commits into
OSGeo:mainfrom
nilason:fix_libgis_implicit_conversion

Conversation

@nilason

@nilason nilason commented Sep 24, 2026

Copy link
Copy Markdown
Contributor

Fix all "Implicit conversion loses precision" warnings in lib/gis, like:

warning: implicit conversion loses integer precision: 'size_t' (aka 'unsigned long') to 'int' 

@github-actions github-actions Bot added C Related code is in C libraries labels Sep 24, 2026
Comment thread lib/gis/cmprzlib.c Resolved
Comment thread lib/gis/cmprzlib.c Resolved
Comment thread lib/gis/make_loc.c Resolved
@echoix

echoix commented Sep 25, 2026

Copy link
Copy Markdown
Member

The repeated windows failures are odd to me; in this and the other similar PR too it fails. Even after 3 reruns

@nilason

nilason commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

The repeated windows failures are odd to me; in this and the other similar PR too it fails. Even after 3 reruns

Yes, indeed.

@nilason

nilason commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

The repeated windows failures are odd to me; in this and the other similar PR too it fails. Even after 3 reruns

Happens elsewhere too, see #7952

@nilason

nilason commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

A probable cause could be mismatch between updated OSGeo4W and cached environment.

@nilason

nilason commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

A probable cause could be mismatch between updated OSGeo4W and cached environment.

@wenzeslaus, @neteler A cache reset might be what we need here.

@neteler

neteler commented Sep 25, 2026

Copy link
Copy Markdown
Member

Do you mean like this:

https://cli.github.com/manual/gh_cache_delete

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

Do you mean like this:

https://cli.github.com/manual/gh_cache_delete

I cleared it all.

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

I had a doubt that something was changed on the osgeo4w side, but only a backport was there 13 hours ago (when I checked at lunchtime 8-9 hours ago it was there). But now there's another commit pushed 2hours ago. Are there other commits that weren't pushed that affects us?

The pytest version is the same as the latest release.

I also launched a rerun of a successful run on main of yesterday. I think that it will probably fail if it has something to do with the environment.

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

The rerun of a previously-passing run failed. https://github.com/OSGeo/grass/actions/runs/36042908364/job/108305431025

I pointed an AI conversation to investigate, and it's getting on a good track: an ABI mismatch with python-gdal with gdal?

The change 13 hours ago (backporting) might have been incomplete, or the rebuild on the server is not finished.

Cc @jef-n: Do you have an insight on what might have gone wrong?

Claude investigation:

Root cause: OSGeo4W gdal package rebuild, not a GRASS code change

Failure symptom: pytest fails to even collect ~99 tests with:

ImportError: DLL load failed while importing _gdal: The specified procedure could not be found.

raised at from osgeo import gdal. Same GRASS commit, same GitHub Actions runner image in both the passing and failing job — so the only variable is what got installed at run time.

Why: the workflow (.github/workflows/osgeo4w.yml) uses the echoix/setup-OSGeo4W action with upgrade-also: true and no version pinning, so every run just pulls whatever is currently newest from download.osgeo.org/osgeo4w/v2/. Between the passing run (2026‑09‑24) and the failing rerun (2026‑09‑26), gdal went 3.13.3-1 → 3.13.3-2 (rebuilt 2026‑09‑25 ~10:47–10:48 UTC, right in the pass/fail window). curl (8.21.0→8.22.0), openssl, and libjpeg-turbo also bumped, but gdal is the prime suspect since it's the only one on the _gdal.pyd codepath.

This isn't a silent build-server change — there's a matching public commit: jef-n/OSGeo4W@60c26bff, "gdal: backport OSGeo/gdal#15007 (fixes qgis/QGIS#66734); curl: update to 8.22.0", timestamped ~30 min after the package upload (consistent with build-then-push, not a discrepancy). That patch backports an upstream GDAL PR reworking curl-thread handling for Windows DLL-unload hangs, and in doing so removes the exported symbol GDALIsInGlobalDestructorFromDLLMain from gcore/gdaldllmain.cpp — plausibly the missing "procedure" the DLL loader can't find.

Last known-good packages still hosted (not yet pruned):

  • https://download.osgeo.org/osgeo4w/v2/x86_64/release/gdal/gdal/gdal-3.13.3-1.tar.bz2
  • https://download.osgeo.org/osgeo4w/v2/x86_64/release/gdal/python3-gdal/python3-gdal-3.13.3-1.tar.bz2

Confidence: high on the timing/culprit match, but not proven at the binary level from logs alone. To actually confirm, you'd want to:

  1. Pin the workflow to gdal-3.13.3-1 / python3-gdal-3.13.3-1 (disable upgrade-also) and rerun — if it passes, that's the smoking gun.
  2. On Windows, dumpbin /exports gdal313.dll | findstr GDALIsInGlobalDestructor and dumpbin /imports _gdal.pyd to find the exact unresolved symbol.
  3. Watch for a -3 rebuild from jef-n that might already fix a regression in the backport.

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

After further investigation, I'm not too sure about gdal being a problem, maybe just msys2 base packages... to be continued

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

Still didn’t find the cause. The oldest job I could rerun from main is from a month ago, and it still fails.

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

Ok I think I have it. (Claude debugging in ci runs on my fork). Essentially, the curl/libcurl uses the new OpenSSL since jef-n/OSGeo4W@d6fc148...b747803#diff-11b789abfab5c961990c23400074fd663571f6c414e8843ffb223139e00de8a1 (2026-09-24), where it jumped from 3.0.22 to 3.5.8.Something looks to have changed in OpenSSL 3.2.

There is a dll loading problem, where the OSGeo4W's python copy of libssl-3-x64.dll is older than the libssl-3-x64.dll shipped by OSGeo4W for use with everything else. Now, on windows, the dll is matched by name, not path, and we end up having the one built in by python loading first, which is missing the symbol SSL_get0_group_name.

So, I think that @jef-n needs to rebuild python for the real fix. I can't really log in easily to osgeo4w's trac, and the github repo doesn't have issues enabled. I'll try again later, if I have time. Otherwise, I encourage someone to file it. There was a commit pushed 3 hours ago (jef-n/OSGeo4W@c15771b) but didn't help to resolve the issue.

Here's the final report of the investigation, with the final run that allowed to find the issue by using cdb to dump loader logs. https://github.com/echoix/grass/actions/runs/36258353652/job/108449299525?pr=713

Details

OSGeo4W: Windows loader picks the wrong libssl-3-x64.dll for libcurl, causing STATUS_ENTRYPOINT_NOT_FOUND

Summary

In the OSGeo4W Python 3.12 package (python3-core), any process that imports Python's built-in ssl module (or anything that imports it, e.g. anyio) before loading a native DLL that depends on bin\libcurl.dll will crash with STATUS_ENTRYPOINT_NOT_FOUND (0xc0000139) the moment that native DLL is loaded. The cause is a Windows DLL-name collision between two independently-versioned copies of libssl-3-x64.dll shipped in the same OSGeo4W tree.

Root cause

OSGeo4W ships two different builds of libssl-3-x64.dll at different paths:

  • C:\OSGeo4W\apps\Python312\DLLs\libssl-3-x64.dll — bundled privately with the python3-core package, used internally by CPython's _ssl.pyd extension module.
  • C:\OSGeo4W\bin\libssl-3-x64.dll — the general-purpose OpenSSL package shared by the rest of OSGeo4W (curl, etc.).

These are not the same build. The bin\ copy is newer and exports SSL_get0_group_name (added in OpenSSL 3.2). The apps\Python312\DLLs\ copy is older and does not export it.

bin\libcurl.dll was rebuilt against the newer OpenSSL and now requires SSL_get0_group_name at load time.

Windows resolves a bare-name import (libssl-3-x64.dll, no path) by first checking whether a module of that filename is already mapped anywhere in the process — regardless of which directory it actually came from. So:

  1. Something imports Python's ssl module early in the process (in our reproduction: the anyio package, imported by pytest at plugin-registration time, does import ssl at module scope).
  2. This loads _ssl.pyd, which delay-loads its own bundled apps\Python312\DLLs\libssl-3-x64.dll (and libcrypto-3-x64.dll) — correct and intentional for Python's own use.
  3. Later, some other component loads bin\libcurl.dll (in our case, transitively, via a third-party application's native library that links against bin\libcurl.dll).
  4. libcurl.dll's import of libssl-3-x64.dll (bare filename) is resolved by the loader to the already-loaded apps\Python312\DLLs\libssl-3-x64.dll instead of bin\libssl-3-x64.dll, because a module with that filename is already resident.
  5. The loader then fails to locate SSL_get0_group_name in that (wrong, older) module and raises STATUS_ENTRYPOINT_NOT_FOUND.

This is confirmed directly from a Windows Loader Snaps trace (FLG_SHOW_LDR_SNAPS, captured via cdb.exe), which shows precisely this sequence, including the exact failing line:

LdrLoadDll - ENTER: DLL name: C:\OSGeo4W\apps\Python312\DLLs\_ssl.pyd
...
LdrpComputeLazyDllPath - INFO: DLL search path computed: C:\OSGeo4W\apps\Python312\DLLs;C:\OSGeo4W\bin;...
ModLoad: ...   C:\OSGeo4W\apps\Python312\DLLs\libcrypto-3-x64.dll
ModLoad: ...   C:\OSGeo4W\apps\Python312\DLLs\libssl-3-x64.dll
...
LdrLoadDll - ENTER: DLL name: C:\OSGeo4W\bin\libcurl.dll
...
LdrpNameToOrdinal - WARNING: Procedure "SSL_get0_group_name" could not be located in DLL at base 0x00007FFBBBB60000.
LdrpReportError - ERROR: Locating export "SSL_get0_group_name" for DLL "C:\OSGeo4W\bin\libcurl.dll" failed with status: 0xc0000139.
LdrpGenericExceptionFilter - ERROR: Function LdrpSnapModule raised exception 0xc0000139

(Base 0x00007FFBBBB60000 is confirmed by the same trace to be C:\OSGeo4W\apps\Python312\DLLs\libssl-3-x64.dll, loaded several hundred microseconds earlier.)

Minimal reproduction

call C:\OSGeo4W\opt\grass\etc\env.bat  REM or any environment with libcurl-dependent native code on PATH
python -c "import ssl; import ctypes; ctypes.CDLL('grass_gis.8.6')"

versus (no crash):

call C:\OSGeo4W\opt\grass\etc\env.bat
python -c "import ctypes; ctypes.CDLL('grass_gis.8.6')"

The only difference is the prior import ssl. Any process that imports ssl before loading a bin\libcurl.dll-dependent DLL will reproduce this, independent of GRASS — GRASS's ctypes bindings just happen to be how we noticed it.

Suggested fixes (any one would resolve it)

  • Rebuild python3-core's private OpenSSL (apps\Python312\DLLs\{libssl,libcrypto}-3-x64.dll) against the same OpenSSL version as the shared bin\ copy, so the two are ABI-compatible even if the wrong one gets reused.
  • Or: have CPython's _ssl.pyd (or the Python package build) use the shared bin\ OpenSSL instead of bundling a private copy, eliminating the duplicate filename entirely.
  • Or: rename one of the two DLLs (e.g. give the Python-private copy a distinct internal/exported name) so a bare-name match can't collide across the two.

Environment

  • OSGeo4W, Windows Server 2022 (GitHub Actions windows-2022 runner image, but reproducible on any OSGeo4W install with this package layout)
  • python3-core (Python 3.12.14)
  • curl/libcurl.dll build requiring SSL_get0_group_name (post the OpenSSL 3.2 rebuild)

@echoix

echoix commented Sep 26, 2026

Copy link
Copy Markdown
Member

Until something changes on the OSGeo4w packages side, we are kinda stuck with any of our PRs

@nilason

nilason commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

Ok I think I have it. …

Really appreciate your digging!

@echoix

echoix commented Sep 27, 2026

Copy link
Copy Markdown
Member

So the package issue is now fixed, and we can just continue with this.

hobu pushed a commit to OSGeo/gdal that referenced this pull request Sep 28, 2026
GDAL curl requests didn't always tear down cleanly on some
platforms and could leave a lock when using GDAL from in
sub-threads. This issue has shown up in a few other places

qgis/QGIS#66734
OSGeo/grass#7947
qgis/QGIS#66496

@echoix echoix left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unlocking you, I don't think there was anything left

@nilason
nilason merged commit 6e39994 into OSGeo:main Oct 3, 2026
26 of 34 checks passed
@github-actions github-actions Bot added this to the 8.6.0 milestone Oct 3, 2026
@nilason
nilason deleted the fix_libgis_implicit_conversion branch October 5, 2026 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C Related code is in C libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants