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

gmp shared library consumers segfault when built with image base > 4GB, headers built for static lib #6983

Closed
jeremyd2019 opened this issue Sep 13, 2020 · 15 comments · Fixed by #7052

Comments

@jeremyd2019
Copy link
Member

I decided to try to debug the gcc segfault when built with high image base today. I build gcc with debug symbols, and the stacktrace disappeared into mpfr, which was not built with debug symbols. I looked at mpfr, saw it depends on gmp, and started out by building those two packages with debug !strip. GMP build succeeded, but after installing the built package, gcc would segfault on lines as simple as "d=1.0;" (the crash I had seen in gcc was in real_from_string).

So, it appears that this gcc issue is actually a GMP issue.

@jeremyd2019
Copy link
Member Author

Oddly, make check for gmp succeeded for both static and shared, but crashes gcc.

@jeremyd2019
Copy link
Member Author

The check of mpfr crashes all over too, so it may be mpfr or something to do with how it interfaces with gmp.

@jeremyd2019
Copy link
Member Author

jeremyd2019 commented Sep 14, 2020

https://gmplib.org/repo/gmp-6.2/file/tip/gmp-h.in#l79

   There's no attempt to support GMP built both static and DLL.  Doing so
   would mean applications would have to tell us which of the two is going
   to be used when linking, and that seems very tedious and error prone if
   using GMP by hand, and equally tedious from a package since autoconf and
   automake don't give much help.

The version of gmp.h installed has __GMP_LIBGMP_DLL set to 0, but mpfr is linking against the dll. It looks like mpfr intends to link against the same type of build as it is (static mpfr = static gmp, dll mpfr = dll gmp), but it's going wrong in the linking.

@jeremyd2019
Copy link
Member Author

Moving libgmp.dll.a away seems to have fixed the mpfr tests. Looks like the issue is that the package is trying to build both static and shared but provide one set of headers, while upstream explicitly does not support that.

@jeremyd2019
Copy link
Member Author

After the successful mpfr, moved on to trying gcc. It ran out of disk space while building stage3, but didn't blow up building libgcc prior to that, so I'd say it's pretty likely that this gmp linking issue is what was causing the problem with gcc.

@mati865
Copy link
Collaborator

mati865 commented Sep 14, 2020

This sounds like pseudo relocations issue that I have described here: #6932 (comment)

You could try to verify it by linking to gmp with --disable-runtime-pseudo-reloc.
I suppose gmp has proper dllexports, in that case so the linker should look if it could use them instead of doing runtime pseudo reloc (AFAIK LLD does that).

@jeremyd2019
Copy link
Member Author

test build of gcc without libgmp.dll.a succeeded. jeremyd2019@3268b9b

@mati865
Copy link
Collaborator

mati865 commented Sep 14, 2020

test build of gcc without libgmp.dll.a succeeded. jeremyd2019@3268b9b

This is expected, symbols from static libraries are included in the final DLL. So there is no relocation.

@jeremyd2019 jeremyd2019 changed the title gmp segfault when built with image base > 4GB gmp shared library consumers segfault when built with image base > 4GB, headers built for static lib Sep 14, 2020
@jeremyd2019
Copy link
Member Author

I think the other option would be to change so that gmp installs shared headers, change mpfr from static to shared (and whatever else may be assuming static headers), and then get gcc built with proper gmp headers. That seemed far more invasive. But that's why I opened this as an issue rather than a pull request, because I don't know which direction would be preferred.

@jeremyd2019
Copy link
Member Author

I'm running a test build now, with gmp switched to install the shared build and only the .a from the static build (rather than vice-versa, installing static and only the .dll{,.a} from the shared), and switching those packages that gcc depends on that want to be the same static or shared as gmp over to build as shared (isl mpc mpfr). It has managed to get through gcc stage1 without crashing, so it seems to have helped. When the build finishes, assuming it's successful, I'll try using the built gcc locally to rebuild gmp without --default-image-base-low (which was needed to keep the existing gcc from crashing as soon as the new gmp was installed).

I don't know if the libraries I found whose configure script checked that they were being built the same static/shared-ness as the GMP headers are the only ones, I only looked at gcc dependencies for this. Also I don't know what other fallout there may be for other packages.

@jeremyd2019
Copy link
Member Author

When the build finishes, assuming it's successful, I'll try using the built gcc locally to rebuild gmp without --default-image-base-low (which was needed to keep the existing gcc from crashing as soon as the new gmp was installed).

The build finished successfully, I was able to rebuild gmp (again) without --default-image-base-low, and that dll didn't cause gcc to crash. This would seem to demonstrate that this header mismatch is the root cause of the issue.

The remaining question is if the preferred solution for the project is to make these libs more static, or more shared.

jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 24, 2020
This requires mpfr, mpc, and isl to be built shared rather than static,
as their configure scripts check that they are being built in the same
static/shared configuration as the gmp headers.

This allows gcc to no longer require the --default-image-base-low flag
on x86_64.  Unfortunately, until gcc is rebuilt with proper linkage, the
gmp dll requires that flag, or the old gcc crashes.

Fixes msys2#6983.
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 24, 2020
Fix eigen3 source since they migrated to gitlab.
@jeremyd2019
Copy link
Member Author

Went ahead and made a pull request with the 'shared' option. Seemed to make the most sense

jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 24, 2020
Fix eigen3 source since they migrated to gitlab.
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 26, 2020
This requires mpfr, mpc, and isl to be built shared rather than static,
as their configure scripts check that they are being built in the same
static/shared configuration as the gmp headers.

This allows gcc to no longer require the --default-image-base-low flag
on x86_64.  Unfortunately, until gcc is rebuilt with proper linkage, the
gmp dll requires that flag, or the old gcc crashes.

Fixes msys2#6983.
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 26, 2020
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 26, 2020
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Sep 28, 2020
@jeremyd2019
Copy link
Member Author

After much debugging and head-scratching, I believe I identified the root cause for why gmp was doing this. #7052 addresses this, but with a pretty nasty hack. It may be preferable to follow upstream's direction and only ship one of static or shared libgmp (#7024). But at least there are options now (once winpthreads hits the repo so i686 can build, that is).

@jeremyd2019
Copy link
Member Author

Originally posted by @Alexpux in #3941 (comment)

issue here is that if I add shared libraries then GCC will link with shared library and if gmp/mpc/mpfr will be updated and DLL name will be changed or export symbols then automatically we get not working GCC.
So right now I will not accept this change

This is actually a pretty strong argument against not only #7024, but shipping a shared libgmp at all. In fact, in these pull requests, I must continue building libgmp with --default-image-base-low until gcc is rebuilt, otherwise gcc immediately starts crashing. I will need to follow up with another pull request to take that flag back out once the newly linked gcc is live.

jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Oct 2, 2020
GMP already knew how do to this on x86, and why, but neglected to apply
the same fix to x86_64.  Fixes msys2#6983.

Rebuild isl, mpc, and mpfr just in case, and gcc to get proper linkage.
jeremyd2019 added a commit to jeremyd2019/MINGW-packages that referenced this issue Oct 2, 2020
@jeremyd2019
Copy link
Member Author

#7101, #7102, #7104 remove workarounds and rebuild the remaining libgmp consumers, which were excluded from #7052 due to how long they take to build. #7103 removes workaround from libgmp dll which was required to keep the existing gcc from crashing long enough to build a new gcc. That should be the last of the fallout from this 🤞

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