SWI-Prolog / packages-xpce

The graphics toolkit for SWI-Prolog
16 stars 14 forks source link

XPCE Visual inspector can crash 64-bit Windows executables starting from V8.5.9 #33

Closed xpxaxsxi closed 1 year ago

xpxaxsxi commented 1 year ago

The 32-bit version are not affected. And Linux versions are all Ok, don't know about Mac.

  1. start up swipl-win.exe
  2. Help>XPCE (GUI) Manual
  3. XPCE Manual>Tools>Emacs
  4. XPCE Manual>Tools>Visual Hierarchy
  5. Now try to open all nodes for Emacs in Visual Hierarchy, it will crash the swipl-win.exe without any warnings

Not 100% sure, but after downloading and installing different versions I think I have found a commit that causes this bug: https://github.com/SWI-Prolog/packages-xpce/commit/b34096b6a31ba1b62c20d2a246adcc3ef7cd1e62

JanWielemaker commented 1 year ago

Thanks. I did all this nicely, but no crash. Both expanding the tree in the tee view and selecting the main editor area.

The code also looks correct. It could use PRIdPTR from <inttypes.h>, but as is intptr_t is the same size as long long on Win64, so this should be fine.

Maybe subtle ways for doing step (5) make the difference?

xpxaxsxi commented 1 year ago

Some versions are not crashing, but clicking Emacs in Visual inspector does not show anything. There should be 3 subitems under Emacs and they all have subitems.

32-bit versions never showed problems, that's a good thing.

I have a cheap laptop 2 core (4 virtual core) and external monitor. Also I tested some versions under a clean system in Windows Sandbox and they behaved as in host system.

Here are versions I tested: 9.1.5 no subitems 9.1.4-55-gf73ff0ba7 no subitems 9.1.4.x86 okay 9.1.0.x86 okay 9.0.4 no subitems 8.5.20 crashes 8.5.20.x86 okay 8.5.14 crashes 8.5.11 crashes 8.5.9 no subitems 8.5.9. x86 okay 8.5.8 okay 8.5.7 okay 8.5.1 okay

I know that from command line it is also possible to query the same data as from Visual Inspector, I havent yet tried that.

8.5.11-1.x64 in a gdb debugger gave this: Thread 7 received signal SIGSEGV, Segmentation fault. [Switching to Thread 27308.0x7078] 0x00007fff8d195c34 in pl2xpce!pceCheckFloatType () from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

I still feel like a newbie with gdb, but maybe this stack trace helps, I don't have source code installed.

0 0x00007fff8d195c34 in pl2xpce!pceCheckFloatType ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

1 0x00007fff8d18c3a1 in pl2xpce!pceGetArgumentTypeGoal ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

2 0x00007fff8d17fa35 in pl2xpce!pceExecuteGoal ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

3 0x00007fff8d236ca7 in setPceThread ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

4 0x00007fff8d2370e1 in setPceThread ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

5 0x00007fff8e26db60 in libswipl!PL_next_solution ()

from /c/Users/pasik/Documents/swidebug/swipl-8.5.11/bin/libswipl.dll

6 0x00007fff8e30528f in libswipl!PL_call_predicate ()

from /c/Users/pasik/Documents/swidebug/swipl-8.5.11/bin/libswipl.dll

7 0x00007fff8d23703f in setPceThread ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

8 0x00007fff8d237101 in setPceThread ()

from /c/users/pasik/documents/swidebug/swipl-8.5.11/bin/pl2xpce.dll

9 0x00007fff8e26dae3 in libswipl!PL_next_solution ()

from /c/Users/pasik/Documents/swidebug/swipl-8.5.11/bin/libswipl.dll

10 0x00007fff8e30528f in libswipl!PL_call_predicate ()

from /c/Users/pasik/Documents/swidebug/swipl-8.5.11/bin/libswipl.dll

JanWielemaker commented 1 year ago

Ok. I changed the old INTPTR_FORMAT with the standard PRIdPTR. Works still find under Wine. Then tried in a Window 11 VM. That indeed crashes. Then recompiled for debugging. This leaves the hierarchy mostly disfunctional (nodes won't expand), but it doesn't crash.

Unfortunately the gdb I downloaded isn't great either. It seems mostly disfunctional :( It can't interrupt, it seems it can't set breakpoints either :cry: Seems you got a stack trace that does make sense. It doesn't connect to the INTPTR_FORMAT in my mind though :cry: From where did you get this functional gdb?

JanWielemaker commented 1 year ago

Fixed :smile: The fundamental issue was the use of PL_put_integer() when marshaling integers from xpce to Prolog. This function takes traditionally a long, which is 4 bytes on Win64. Now uses PL_put_int64(). This has always been like this. The difference between working and not depends on the memory layout as the visual hierarchy using object references as integers to avoid affecting the memory management of the observed objects. If the object was in (too) high addresses it would fail.

xpxaxsxi commented 1 year ago

I'll explain the gdb in Windows 10. I first did this in december 2022, it was a chance to learn about gdb debugging, so this was a first newbie project.

I built the software in a Linux machine, installed software to a Windows 10 machine and then in Windows 10 machine debugged it.

  1. Install msys2 https://www.msys2.org/
  2. try gdb on command line, it says not found
  3. Install gdb (this was a tricky thing, I spent few hours to how to do it, tried few wrong ways) install it using the pacmanpackage handler in the msys2 prompt
    pacman gdb #or something similar
  4. setup https://github.com/SWI-Prolog docker-swipl-build-mingw
  5. build a debug version with cmake I first made a release version in build_win64 directory and then built a debug version to same directory, this very propably caused problems: I could not make a NSIS installer that would install debug version executables. Cmake made a NSIS installer that used release versions even though I commanded it to do a debug version. I gave up after few failed attempts I did things wrong, now I was unable to run installer in Windows 10
  6. Because I had a NSIS installer that installed release executables without problems: installed the release version that I built in Linux machine, installed that to my Windows 10 copied the pl2xpce.dll debug version over the release version. Debug version of pl2xpce is about 300 megabytes and release version is under 10 megabytes.
  7. copied the source files from Linux to Windows 10
  8. tried to get gdb to something sensible for the newbie me.
  9. after few evenings I think I had enough experience about gdb and tried to do serious debugging
  10. after few more evenings I gave up, because the internal machinery of XPCE was too difficult

Anyway I learned a lot of valuable things about: msys2, gdb, NSIS, cmake etc. etc. etc. even though my main objective to fix https://github.com/SWI-Prolog/packages-xpce/issues/31 was not a success, you Jan fixed that issue later.

JanWielemaker commented 1 year ago

Thanks. The setup can be a bit more smooth. I run Windows (11) in a VirtualBox VM on the Linux host. I turned the swipl-devel tree into a shared folder, so I can access it from Windows and Linux. Now build using the build docker. You can run the result in Linux using wine src/swipl[-win].exe (both in the build container and on the host) as well as in windows by going to the build.win64 directory and staring src\swipl[-win].exe

I always had trouble finding a version of gdb that really worked. I had one on an older Windows installation ... So the MYS2 route seems to be the right way.

Luckily for most bugs I can do the gdb work on the Linux version :smile: In this case it would have been handy. Now I had to use quite a few printf statements to figure out where the value was truncated to 32 bits :cry: But, using the shared solution this is pretty fast: edit one of the xpce files, run ninja src/xpce2pl.dll to just update the dll, run (in wine once I found the problem was truncation to 32-bit), etc.

xpxaxsxi commented 1 year ago

Beginners luck if I found a proper gdb. MSYS2 has 7 flavours! . I think I first used the default UCRT64, I think a better one would be MINGW64.

It is always fun to find a bug and then get if fixed! Thanks.