nspire-emus / firebird

Multi-platform emulator of TI Nspire calculators
GNU General Public License v3.0
691 stars 68 forks source link

[HELP] Cannot get GDB to work (Windows) #259

Closed m-doescode closed 2 years ago

m-doescode commented 2 years ago

Excuse me if this was already answered, could not find it with a google search/issue search.

Hello, I'm trying to debug on my app on firebird using GDB. However, I've found my attempts unsuccessful. Do you think you can help me?

System information

Running Windows 10 21H1 build 19043 Cygwin version 3.3.4(0.341/5/3) GDB version 10.2 Latest firebird Latest ndless-sdk

Problem

I cannot get GDB to debug in firebird. Whenever I type the following:

arm-none-eabi-gdb -ex "target remote 127.0.0.1:3333" helloworld-sdl.elf

I get the following in the debugger tab of firebird:

Unsupported GDB cmd 'qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+'

Then GDB tells me:

Reading symbols from helloworld-sdl.elf...
Remote debugging using 127.0.0.1:3333
Remote communication error.  Target disconnected.: Broken pipe.

What I've tried

  1. Downgrading to an older version of GDB (Cygwin 7.9.1-1)
  2. Restarting
  3. Turning off anti-virus
  4. Changing the port
  5. Restarting without snapshot
Vogtinator commented 2 years ago

I suspect some issue with the windows specific socket handling. Can you capture the traffic with e.g. wireshark?

Vogtinator commented 2 years ago

You can also try set debug remote 1 in gdb before target remote

m-doescode commented 2 years ago

You can also try set debug remote 1 in gdb before target remote

This is the result I get:

Remote debugging using 127.0.0.1:3333
[remote] start_remote: enter
  [remote] Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+#ec
  [remote] Received Ack
  [remote] Packet received:
  [remote] packet_ok: Packet qSupported (supported-packets) is NOT supported
  [remote] Sending packet: $vMustReplyEmpty#3a
[remote] start_remote: exit
Remote communication error.  Target disconnected.: Broken pipe.
m-doescode commented 2 years ago

I'm guessing the issue is that GDB tries to send a qSupported command to firebird, but firebird is unable to handle it. (core/gdbstub.c).

But this is strange, as I've tried older versions of GDB with no luck, and other people have reported it working just fine. I'm not sure if this is a Windows only error, or if this is the same for all other versions.

Vogtinator commented 2 years ago

qSupported is not supported, but that's fine. A working session looks like this:

  [remote] Sending packet: $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+;xmlRegisters=i386#77
  [remote] Received Ack
  [remote] Packet received: 
  [remote] packet_ok: Packet qSupported (supported-packets) is NOT supported
  [remote] Sending packet: $vMustReplyEmpty#3a
  [remote] Received Ack
  [remote] Packet received: 
  [remote] Sending packet: $Hg0#df
  [remote] Received Ack
  [remote] Packet received: 
  [remote] Sending packet: $qTStatus#49
  [remote] Received Ack
  [remote] Packet received: 
  [remote] packet_ok: Packet qTStatus (trace-status) is NOT supported
  [remote] Sending packet: $?#3f
  [remote] Received Ack
  [remote] Packet received: T05thread:1;0d:58e20018;0f:8c352113;
  [remote] Sending packet: $qfThreadInfo#bb
  [remote] Received Ack
  [remote] Packet received: m1
  [remote] Sending packet: $qsThreadInfo#c8
  [remote] Received Ack
  [remote] Packet received: l
  [remote] Sending packet: $qAttached#8f
  [remote] Received Ack
  [remote] Packet received: 
  [remote] packet_ok: Packet qAttached (query-attached) is NOT supported

Can you get a packet dump?

m-doescode commented 2 years ago

Can you get a packet dump?

I'm not quite sure how to. I'm not very familiar with WireShark.

I've been using burp suite recently but it doesn't seem to work for localhost.

Vogtinator commented 2 years ago

You could try something like https://www.netresec.com/?page=RawCap

m-doescode commented 2 years ago

Oh, thanks! RawCap worked well.

This is what it captured:

dumpfile.pcap ``` ¡²ÃÔ   ÿÿ ebQÎ ¶ê 4 4E 4)@ €   ÌC ê=°) €ÿÿ: ÿ×bQÎ ¢ 4 4E 4*@ €    ÌC±2§ê=°*€ÿÿm ÿ×bQÎ ¢ ( (E (+@ €   ÌC ê=°*±2¨P'ù2k bQÎ ¢ ) )E ),@ €   ÌC ê=°*±2¨P'ùb +bQÎ ¢ ( (E (-@ €    ÌC±2¨ê=°+P'ù2j bQÎ ¢ Å ÅE Å.@ €   ÌC ê=°+±2¨P'ù ´ $qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+#ecbQÎ ¢ ( (E (/@ €    ÌC±2¨ê=°ÈP'ø1Î bQÎ ñ ) )E )0@ €    ÌC±2¨ê=°ÈP'øÅ +bQÎ ñ ( (E (1@ €   ÌC ê=°È±2©P'ù1Ì bQÎ ñ , ,E ,2@ €    ÌC±2©ê=°ÈP'øÝm $#00bQÎ ñ ( (E (3@ €   ÌC ê=°È±2­P'ù1È bQÎ ñ ( (E (4@ €    ÌC±2­ê=°ÈP'ø1È bQÎ ñ ( (E (5@ €   ÌC ê=°È±2®P'ù1Ç bQÎ ñ ) )E )6@ €   ÌC ê=°È±2®P'ù¾ +bQÎ ñ ( (E (7@ €    ÌC±2®ê=°ÉP Y» bQÏ  ~ ? ?E ?äµ@ @ӏÀ¨ À¨ ÿ®=<ð +IÊSEARCH BSDP/0.1 DEVICE=0 SERVICE=1 bQÓ Éo 4 4E 49@ €   Á i´Ö²_¯ž¡#€'÷~ó  ¯ž¡"¯ž¡#bQÓ Éo ) )E )8@ €   i´Á ¯ž¡"Ö²_P'øV bQÓ  Ü 4 4E 4;@ €   i´Á ¯ž¡#Ö²_€'ø²  Ö²^Ö²_bQÓ  Ü ) )E ):@ €   Á i´Ö²^¯ž¡#P'÷VŽ bQÕ 0 ? ?E ?æà@ @ÑdÀ¨ À¨ ÿæq<ð +–SEARCH BSDP/0.1 DEVICE=0 SERVICE=1 ```
Vogtinator commented 2 years ago

Can you add that file as attachment?

m-doescode commented 2 years ago

Can you add that file as attachment?

Sure: dumpfile.zip

Vogtinator commented 2 years ago

Looks like firebird terminates the connection after sending the empty reply to qSupported. I think the GDB socket is set as nonblocking, and so getpacket() -> get_debug_char() returns a failure instead of blocking until data arrives. If so, that was probably broken by 8e79eff05563376ba95f06b67ebc8271473ed2e0 already.

Can you build firebird from source? I currently don't have a windows build setup...

m-doescode commented 2 years ago

Looks like firebird terminates the connection after sending the empty reply to qSupported. I think the GDB socket is set as nonblocking, and so getpacket() -> get_debug_char() returns a failure instead of blocking until data arrives. If so, that was probably broken by 8e79eff already.

Can you build firebird from source? I currently don't have a windows build setup...

Alright, I'll try to do so and I'll get back to you once it's done.

Vogtinator commented 2 years ago

Great! To confirm the theory, it should be enough to edit core/gdbstub.c to change set_nonblocking(socket_fd, true); to set_nonblocking(socket_fd, false);.

m-doescode commented 2 years ago

Great! To confirm the theory, it should be enough to edit core/gdbstub.c to change set_nonblocking(socket_fd, true); to set_nonblocking(socket_fd, false);.

After I run qmake .., when I run make, I get the following error:

make -f Makefile.Release
make[1]: Entering directory '/cygdrive/c/Users/XXXX/Documents/ndless/Firebird Emu 1.5/build'
Makefile.Release:269: *** missing separator.  Stop.
make[1]: Leaving directory '/cygdrive/c/Users/XXXX/Documents/ndless/Firebird Emu 1.5/build'
make: *** [Makefile:37: release] Error 2

What should I do?

Contents of build: build.zip

Vogtinator commented 2 years ago

It looks like you're building it with the msvc toolchain, you'll have to use GCC or clang. Additionally the generated Makefile seems to have issues with spaces...

m-doescode commented 2 years ago

It looks like you're building it with the msvc toolchain, you'll have to use GCC or clang. Additionally the generated Makefile seems to have issues with spaces...

Ahh, that clears things up. I'm assuming you mean qmake? As for the Makefile having spaces, I'm guessing I can just run it through dos2unix, right?

m-doescode commented 2 years ago

I may have screwed something up along the way during the process.

When I run make this time, Makefile doesn't error. However, I get syntax errors while compiling:

In file included from /usr/include/qt5/QtNetwork/QtNetwork:32,
                 from /usr/include/qt5/QtQml/QtQmlDepends:4,
                 from /usr/include/qt5/QtQml/QtQml:3,
                 from ../qmlbridge.h:5,
                 from ../mainwindow.h:13,
                 from ../mainwindow.cpp:20:
/usr/include/qt5/QtNetwork/qnetworksession.h:96:32: error: expected identifier before ‘(’ token     
   96 |     QNetworkInterface interface() const;
      |                                ^
/usr/include/qt5/QtNetwork/qnetworksession.h:96:33: error: expected unqualified-id before ‘)’ token 
   96 |     QNetworkInterface interface() const;
      |                                 ^
make: *** [Makefile:894: main.o] Error 1
make: *** [Makefile:884: mainwindow.o] Error 1
In file included from /usr/include/qt5/QtNetwork/QtNetwork:32,
                 from /usr/include/qt5/QtQml/QtQmlDepends:4,
                 from /usr/include/qt5/QtQml/QtQml:3,
                 from ../qmlbridge.h:5,
                 from ../mainwindow.h:13,
                 from moc_mainwindow.cpp:9:
/usr/include/qt5/QtNetwork/qnetworksession.h:96:32: error: expected identifier before ‘(’ token     
   96 |     QNetworkInterface interface() const;
      |                                ^
/usr/include/qt5/QtNetwork/qnetworksession.h:96:33: error: expected unqualified-id before ‘)’ token 
   96 |     QNetworkInterface interface() const;
      |                                 ^
make: *** [Makefile:1248: moc_mainwindow.o] Error 1
make: Target 'first' not remade because of errors.

(If it is important, interface is a macro to __STRUCT__ which is a macro to struct. This is bad because there seems to be a custom definition of interface which collides with this macro. There is a #if check at the top and an #undef, but it only executes if Q_OS_WIN is defined which it is not because I am running on Cygwin)

To clarify, this is what I did:

  1. Installed libQt5Core-devel
  2. Installed libKF5Declarative5 and -devel
  3. I ran git submodule init/update
  4. I ran qmake ..
  5. I ran make -r -j12
Vogtinator commented 2 years ago

I may have screwed something up along the way during the process.

When I run make this time, Makefile doesn't error. However, I get syntax errors while compiling:

In file included from /usr/include/qt5/QtNetwork/QtNetwork:32,
                 from /usr/include/qt5/QtQml/QtQmlDepends:4,
                 from /usr/include/qt5/QtQml/QtQml:3,
                 from ../qmlbridge.h:5,
                 from ../mainwindow.h:13,
                 from ../mainwindow.cpp:20:
/usr/include/qt5/QtNetwork/qnetworksession.h:96:32: error: expected identifier before ‘(’ token     
   96 |     QNetworkInterface interface() const;
      |                                ^
/usr/include/qt5/QtNetwork/qnetworksession.h:96:33: error: expected unqualified-id before ‘)’ token 
   96 |     QNetworkInterface interface() const;
      |                                 ^
make: *** [Makefile:894: main.o] Error 1
make: *** [Makefile:884: mainwindow.o] Error 1
In file included from /usr/include/qt5/QtNetwork/QtNetwork:32,
                 from /usr/include/qt5/QtQml/QtQmlDepends:4,
                 from /usr/include/qt5/QtQml/QtQml:3,
                 from ../qmlbridge.h:5,
                 from ../mainwindow.h:13,
                 from moc_mainwindow.cpp:9:
/usr/include/qt5/QtNetwork/qnetworksession.h:96:32: error: expected identifier before ‘(’ token     
   96 |     QNetworkInterface interface() const;
      |                                ^
/usr/include/qt5/QtNetwork/qnetworksession.h:96:33: error: expected unqualified-id before ‘)’ token 
   96 |     QNetworkInterface interface() const;
      |                                 ^
make: *** [Makefile:1248: moc_mainwindow.o] Error 1
make: Target 'first' not remade because of errors.

(If it is important, interface is a macro to __STRUCT__ which is a macro to struct. This is bad because there seems to be a custom definition of interface which collides with this macro. There is a #if check at the top and an #undef, but it only executes if Q_OS_WIN is defined which it is not because I am running on Cygwin)

You probably shouldn't try building this in Cygwin, it'll use a different runtime than the more native windows builds. Apparently Qt isn't compatible with that already.

m-doescode commented 2 years ago

You probably shouldn't try building this in Cygwin, it'll use a different runtime than the more native windows builds. Apparently Qt isn't compatible with that already.

I see... What should I use to build it, MinGW, or is there a make that comes with Qt?

Vogtinator commented 2 years ago

The Qt installer for Windows comes with a MinGW toolchain.

m-doescode commented 2 years ago

Ok, so this comment (yes this one) was supposed to be about how I couldn't build it in Qt Creator, but it turns out it was just because cygwin was interfering (somehow?) by being in the path. When I removed it from the path environment variable, it built just fine.

Time to test!

(Edit: After re-adding Cygwin to path, it seems to still work. So I have no idea what I was doing wrong.)

m-doescode commented 2 years ago

Well this is awkward, not sure if it's something I've done wrong or if it was broken by a commit but it doesn't want to start the emulation. I've put the flash, boot1, and everything in place, but when I click "Start", it does nothing. image

No errors in Application Output.

16:43:09: Debugging starts
QML debugging is enabled. Only use this in a safe environment.
NVD3DREL: 
GR-805 : DX9 Overlay is DISABLED

Compile output, if it really matters

General messages has something interesting:

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-g++.exe -x c++ -E -dM -" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-g++.exe -dumpmachine" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-g++.exe -print-search-dirs" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc-11.2.0.exe -x c -E -dM -" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc-11.2.0.exe -dumpmachine" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc-11.2.0.exe -print-search-dirs" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc.exe -x c -E -dM -" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc.exe -dumpmachine" terminated abnormally.

Compiler feature detection failure!
The command "C:\Users\Majd\Documents\ndless\Ndless\ndless-sdk\toolchain\install\bin\arm-none-eabi-gcc.exe -print-search-dirs" terminated abnormally.

Running Windows Runtime device detection.
No winrtrunner.exe found.
Running Windows Runtime device detection.
No winrtrunner.exe found.
Running Windows Runtime device detection.
No winrtrunner.exe found.
Project MESSAGE: FB_ARCH: x86
Project MESSAGE: TRANSLATION_ENABLED: true
Project MESSAGE: SUPPORT_LINUX: true
Project MESSAGE: FB_ARCH: x86
Project MESSAGE: TRANSLATION_ENABLED: true
Project MESSAGE: SUPPORT_LINUX: true
Project MESSAGE: FB_ARCH: x86
Project MESSAGE: TRANSLATION_ENABLED: true
Project MESSAGE: SUPPORT_LINUX: true
Project MESSAGE: FB_ARCH: x86
Project MESSAGE: TRANSLATION_ENABLED: true
Project MESSAGE: SUPPORT_LINUX: true

(Note: the errors about missing cygwin libraries disappear after re-adding cygwin to path, yet somehow this time it doesn't break?)

Vogtinator commented 2 years ago

Anything in the debugger output? If you enter the debugger, does that work?

You could try to build the v1.5 tag, which is known to work. If that works, it might've been broken by some later change, maybe the 64bit Windows support.

m-doescode commented 2 years ago

Anything in the debugger output? If you enter the debugger, does that work?

Well... I suppose it's confusing seen as there is two debuggers...

I can debug with Qt just fine.

This time, when I attempt to connect GDB, I no longer get "Broken pipe", instead I get "Remote communication error. Target disconnected.: Connection reset by peer." Which at least means we've made some progress, right?

Anyway... There is nothing different in the debugger output of Firebird apart from the error about ndless:

Ndless not detected or too old. Debugging of applications not available!
Unsupported GDB cmd 'qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+'

Maybe it isn't working because there is nothing running?

You could try to build the v1.5 tag, which is known to work. If that works, it might've been broken by some later change, maybe the 64bit Windows support.

I will try to do that now. I will let you know if anything changes.

Once again, thank you very much for your help!

Vogtinator commented 2 years ago

Anything in the debugger output? If you enter the debugger, does that work?

Well... I suppose it's confusing seen as there is two debuggers...

I can debug with Qt just fine.

Right, I meant Firebird's debugger in this case. If it can be entered, the emulation is at least trying to run...

This time, when I attempt to connect GDB, I no longer get "Broken pipe", instead I get "Remote communication error. Target disconnected.: Connection reset by peer." Which at least means we've made some progress, right?

Could also be a step backwards, hard to say.

Anyway... There is nothing different in the debugger output of Firebird apart from the error about ndless:

Ndless not detected or too old. Debugging of applications not available!
Unsupported GDB cmd 'qSupported:multiprocess+;swbreak+;hwbreak+;qRelocInsn+;fork-events+;vfork-events+;exec-events+;vContSupported+;QThreadEvents+;no-resumed+;memory-tagging+'

Maybe it isn't working because there is nothing running?

If it gets that far it should complete the connection at least.

You could try to build the v1.5 tag, which is known to work. If that works, it might've been broken by some later change, maybe the 64bit Windows support.

I will try to do that now. I will let you know if anything changes.

Once again, thank you very much for your help!

Thanks for doing the tests!

m-doescode commented 2 years ago

Hmm...

I ran the following commands:

git stash # to stash the changes to gdbstub.c
git checkout tags/v1.5 -b tag-v1.5 # switch to tag "v1.5"
git stash pop

and when I built, it still didn't work.

It is likely something wrong with the I'm building it. (Note that I also took Cygwin off PATH because it wasn't working otherwise. Potentially could be a factor of issue?)

Vogtinator commented 2 years ago

Could be. Unfortunately I can't really tell what's going wrong. Could be a lot of things...

I should get access to my Win dev env soon again, so I'll have a try as well.

m-doescode commented 2 years ago

Could be. Unfortunately I can't really tell what's going wrong. Could be a lot of things...

I should get access to my Win dev env soon again, so I'll have a try as well.

Sorry for not providing you with much info. Thanks for the help!

Vogtinator commented 2 years ago

I could reproduce the issue easily and my suspicion was correct, enabling blocking reads again made the connection work. To fix it properly, I implemented polling on Windows in #260.

Here's a test build: firebird-emu.zip You'll have to put the file inside the directory of the 1.5 download.

m-doescode commented 2 years ago

Yes! It worked!

Thank you very much for all of your help! I am very appreciative!

Have an awesome day!

Vogtinator commented 2 years ago

Thanks for testing, that was incredibly quick!

grubsteak commented 1 year ago

Okay, so I am trying to debug my program using Firebird 1.5 on Windows using GDB and I'm running into this bug still.

I first start arm-none-eabi-gdb directly from Ndless/ndless-sdk/toolchain/install/bin

Here is my GDB output

(gdb) set remote supported-packets-packet off <-- I also had to do this
(gdb) set debug remote 1  
(gdb) target remote host.docker.internal:3333
Remote debugging using host.docker.internal:3333
[remote] start_remote: enter
  [remote] Sending packet: $vMustReplyEmpty#3a
  [remote] Received Ack
  [remote] Packet received: 
  [remote] Sending packet: $Hg0#df
[remote] start_remote: exit
Remote connection closed

and here is the output in the firebird-emu console

Unsupported GDB cmd 'vMustReplyEmpty'

So it seems like firebird is still prematurely closing sockets on Windows. I even tried the test build above and it still did not work.

Here it says that all you have to do for unknown 'v' packets is to just return an empty string I would try to patch Firebird to fix this and submit a pull request, but I am scared of using Qt (especially on Windows).

Vogtinator commented 1 year ago

That looks like the original bug, but not totally the same. The Unsupported GDB cmd messages are fine and actually useful here, there should be multiple of those in a working session.

Here it says that all you have to do for unknown 'v' packets is to just return an empty string I would try to patch Firebird to fix this and submit a pull request, but I am scared of using Qt (especially on Windows).

FB handles that correctly, which is visible in the [remote] Packet received: line: gdb received an empty string.

Can you try one of the builds from https://github.com/nspire-emus/firebird/actions/runs/3795934362?

grubsteak commented 1 year ago

It works! Thanks!!!