Remote GDB Debugger issues

There are several issues in IDA related to GDB remote debugging. The following concerns debugging windows programs.

IDA does not show correct destination of logical addresses involving fs or gs overrides, for example:

mov eax, fs:18h    ;clicking on this goes to an address 0x18 instead of fs_base + 0x18
mov eax, gs:30h    ;same here, goes to 0x30 instead of gs_base + 0x30

At the same time, GDB stub provides fs_base and gs_base registers. Here is a tcpdump of the interaction with GDB stub:

>> from IDA to remote stub
qXfer:features:read:64bit-segments.xml:0,1023

<< from remote stub to IDA
l<?xml version="1.0"?>
<!-- Copyright (C) 2016-2018 Free Software Foundation, Inc.

     Copying and distribution of this file, with or without modification,
     are permitted in any medium without royalty provided the copyright
     notice and this notice are preserved.  -->

<!DOCTYPE feature SYSTEM "gdb-target.dtd">
<feature name="org.gnu.gdb.i386.segments">
  <reg name="fs_base" bitsize="64" type="int"/>
  <reg name="gs_base" bitsize="64" type="int"/>
</feature>

IDA is supposed to show thread names in Threads debugging window. Instead it shows only FFFFFFFFFFFFFFFF regardless of thread names

an example conversation shows that names are set:

<< from IDA
qXfer:threads:read::0,1023

>> to IDA
l<threads>
<thread id="1" core="0" name="main thread" />
<thread id="2" core="0" name="thread #1" />
<thread id="3" core="0" name="thread #2" />
</threads>

But all the names are FFFFFFFFFFFFFFFF in Threads window.

Choose process to attach to window does not show process name

IDA can make a request qXfer:exec-file:read to read the name of the program. When attaching to the remote process a window Choose process to attach to appears. It has two fields: Id and Name. Name is always <attach to the process started on target> regardless of the process name, that can be obtained through qXfer:exec-file:read request.

Duplicated program name in Modules window

As I noticed, IDA makes qXfer:exec-file:read to get the name of the running program. Let’s assume that the process name is c:\test.exe. This name is shown in Modules window without base address (ok, it’s not known by default). But if GDB stub provides program’s name in the loaded libraries like this:

<< from IDA
qXfer:libraries:read::0,1023

>> to IDA
l<library-list>
    <library name="c:\windows\system32\win32u.dll"><segment address="0x100001000"/></library>
    <library name="c:\test.exe"><segment address="0x140001000"/></library>
    <library name="c:\windows\system32\ntdll.dll"><segment address="0x180001000"/></library>
</library-list>

then Modules window will contain duplicated entry for the program name:

Path                            Base                Size
c:\windows\system32\win32u.dll	0000000100000000	0000000000022000
c:\test.exe	                    0000000140000000	0000000000009000
c:\windows\system32\ntdll.dll	0000000180000000	00000000001F8000
c:\test.exe

Some symbols disappear when using Load debug symbols in Modules window

Attach to a program. Load ntdll.dll symbols. Go to LdrLoadDll and find this line in its prolog:

mov     rax, cs:__security_cookie

Then load symbols for another module. Look at LdrLoadDll’s prolog again and notice a missed name:

mov     rax, cs:off_180184510

WOW64 debugging problems

When debugging WOW64 processes we have a mix of 64/32-bit modules. IDA does not respect module bitness. It loads all the modules as 64-bit. Moreover, if I manually set segment bitness (Alt-S) for such a module to 32-bit, IDA can revert it back to 64-bit during program execution (I think it depends on other module loading).

Hi @lvm,
Thank you for the extensive report!
A few more details would likely help us to investigate it further. Would you be able to share with us:

  • The exact GDB server you are using
  • Your IDA version and your system version
  • Sample idb (you can add it via our support channel)

Hi @teresa_hexrays,

The exact GDP server you are using

The GDB server is from the windows emulator.
Unfortunately the release version is not suitable for thorough checking. Currently I’m working on enhancing the GDB support and I didn’t yet make a PR with all the stuff.

So, I uploaded my build here, it is a 7-zip archive with password emulator. Below are the setup instructions.

  1. Use a virtual machine with Windows 10 installed.
  2. Download an archive and unpack it to a directory, e.g. c:\test
  3. Create an emulation root (run under elevated command prompt):
> cd /d c:\test
> create-root.bat
> dump-apiset.exe
> move api-set.bin root
  1. Run the emulator
    analyzer.exe -d -e c:\test\root -p c:\test.exe some_sample.exe c:\test.exe

Substitute some_sample.exe with the path to a sample. You can use threads-64.exe or threads-32.exe from the archive to test thread names.

At first, you can omit -d (Enable GDB debugging mode) to test that everything is ok.

  1. GDB stub listens on 127.0.0.1:28960 and is ready to work

Your IDA version and your system version

9.2, Windows 10 22H2

Sample idb (you can add it via our support channel)

I don’t load any sample to the database initially. I use an empty (“Work on your own”) database.
Then I set up the debugger:

Go to DebuggerAttachRemote GDB Debugger and set

Hostname: localhost
Port: 28960

Configuration: Intel x64 (this is by default)

I forgot to mention another issue. This is not yet implemented in my build but I want to implement it.

The original gdb and it’s gdbserver are using stop signal 0 as a notification that something happened during execution: a library is loaded/unloaded, a thread is created/killed and so on. On the other hand, it seems that IDA does not take such a signal into account (moreover sometimes it shows a message that the signal 0 is unknown).

This is a sample conversation between the original gdb and gdbserver:

<< from gdb; gdb continues execution
vCont;c

>> from gdbserver; it sends a signal 0 with reasons why it is stopped. in this case it is stopped because some library was loaded / unloaded
T0006:f*,;07:28e57f0*&;10:a4dac40dfc7f0* ;thread:7038;library:;

<< from gdb 
[ .. gdb requests libraries and all the stuff, prints some messages on the screen (if any) .. ]

<< from gdb; gdb continues without user interaction
vCont;c

Hi, just a quick follow-up! These issues have been fixed on our end and are targeted for the next release (9.4).

Hi! Thank you, that’s nice to hear!

Could you re-test? The GDB client was overhauled in 9.4 beta1 and Sogen specifically was tested, but another pair of eyes would be great!

Hi! Just retested.

Unfortunately, some bugs still appear.

  1. IDA still does not follow the correct destination of logical addresses involving fs or gs overrides. In comparison, this works well when using Local Windows debugger.
  2. Some symbols still disappear when using Load debug symbols in Modules window (or when symbols are autoloaded).
  3. WOW64 debugging issues still exist.

Perhaps I should provide more detailed instructions on how to reproduce the errors.

  1. Get the latest build artifacts of sogen:
    • get the emulated environment: download Windows 2025 Emulation Root
    • get the emulator itself: download Windows x86_64 Release Artifacts (or macOS arm64 Release Artifacts, Linux x86_64 Clang Release Artifacts depending on your platform)
    • get the x86 build: Windows x86 Release Artifacts
  2. Extract archives (each .zip contains .tar, so extract from zip then tar) to a folder of your choise, e.g. ~/emulator:
    • extract everything from Windows 2025 Emulation Root.zip to a folder ~/emulator
    • extract analyzer.exe and *.dll from Windows x86_64 Release Artifacts.zip to ~/emulator
    • extract test_sample.exe from Windows x86 Release Artifacts.zip to ~/emulator/filesys/c/
  3. cd to ~/emulator and run analyzer.exe -d -e . c:/test-sample.exe
  4. Run IDA, then DebuggerAttachRemote GDB debugger, fill-in parameters Hostname: localhost, Port: 28960, then start debugging

Now we can reproduce the bugs:

  1. Go to 0x1800EB20E, you’ll see
    mov rax, gs:60h
    When you click on gs:60h you’ll go to 0x60 instead of GS_BASE + 0x60 (= 0x260060)
  2. Load symbols for c:\windows\system32\ntdll.dll (64-bit module).
    Go to LdrLoadDll and notice a line of code
    18003F8C2 mov rax, cs:__security_cookie
    Now load symbols for c:\windows\system32\win32u.dll.
    You will see that the previous line has changed:
    18003F8C2 mov rax, cs:off_1801E6598
  3. Load symbols for c:\windows\syswow64\ntdll.dll (32-bit module).
    Go to LdrLoadDll (in 32-bit version of ntdll.dll), put a breakpoint on it, then press Alt-S and see that the segment bitness is incorrect (64). Change the bitness to 32 bit.
    Press F9 and the breakpoint will hit. Press Alt-S again and see, that the bitness reverted back to the incorrect value (64).

@teresa_hexrays can you look here, pls.

Oh, I forgot to mention another issue with the GDB qRcmd packet. This bug has not been reported yet.

There is an inconsistency in the handling of the qRcmd packet (i.e. when sending a remote command to the GDB server). It seems IDA doesn’t take into account the fact that executing a remote command can take a long time.

  1. The original GDB assumes that the command being executed may take a long time to execute. See remote_target::rcmd.

  2. At the same time the manual says that before the final result packet, the target may also respond with a number of intermediate Ooutput console output packets.

In IDA, if a command takes too long to execute, even when using intermediate output commands, I get this:

<error sending command to monitor>

(I can’t provide an example to reproduce this issue because sogen releases doesn’t currently support remote commands.)

Hi @lvm,

First of all, thank you for taking the time to retest these issues. We’ve logged an internal ticket to investigate it further - we’ll keep you updated on any findings or fixes.

Thanks for your detailed reports. I reproduced and fixed all 3 bugs and implemented qRcmd timeout handling the same as GDB to support long-running commands. Note that you can also increase the general GDB timeout in the menu/config if necessary. The changes will be in the next 9.4 beta/rc.

Connecting to qemu without a project loaded using attach with gdb localhost:1234 results in a 1783 crash, you should be able to replicate it 1:1 with default settings

Thank you! Indeed, it seems we have an issue in this workflow. We’ll have a look at it.

@lvm Could you try 9.4 beta 2 RC1? It was released to the portal today.

Oh, nice! It’s working now. Thank you!