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

catchsegv not resolving gnu_debuglink correctly #65

Closed
alvinhochun opened this issue Apr 11, 2022 · 8 comments
Closed

catchsegv not resolving gnu_debuglink correctly #65

alvinhochun opened this issue Apr 11, 2022 · 8 comments
Labels

Comments

@alvinhochun
Copy link
Contributor

Filing a new issue from #64 (comment)

The ImageName argument seems wrong? You can also see that

OutputDebug("MGWHELP: %s - not found\n", debugImageStr);
is printing a path with the wrong directory.

Z:\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin>d:\dev\toolchain\mingw\x86_64-11.2.0-release-posix-seh-rt_v9-rev1\bin\gdb --args catchsegv -m krita.com
d:\dev\toolchain\mingw\x86_64-11.2.0-release-posix-seh-rt_v9-rev1\bin\gdborig.exe: warning: Couldn't determine a path for the index cache directory.
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from catchsegv...
(gdb) b mgwhelp.cpp:240
No source file named mgwhelp.cpp.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (mgwhelp.cpp:240) pending.
(gdb) r
Starting program: Z:\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\catchsegv.exe -v -m krita.com
[New Thread 14264.0x52b4]
[New Thread 14264.0x5908]
[New Thread 14264.0x1610]
CREATE_PROCESS PID=13776 TID=22388 lpBaseOfImage=00007FF7E4C40000

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x178, ImageName=0x5fdd4ff2d0 "\a", Base=140702671699968) at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb) c
Continuing.
[New Thread 14264.0x5d6c]
warning: MGWHELP: krita.com.debug - not found
LOAD_DLL PID=13776 TID=22388 lpBaseOfDll=00007FFAA4D50000 ntdll.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x238, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ntdll.dll", Base=140714483974144)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb) c
Continuing.
LOAD_DLL PID=13776 TID=22388 lpBaseOfDll=00007FFAA3020000 kernel32.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x240, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\kernel32.dll", Base=140714453368832)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
LOAD_DLL PID=13776 TID=22388 lpBaseOfDll=00007FFAA24F0000 KernelBase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x248, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\KernelBase.dll", Base=140714441637888)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
CREATE_THREAD PID=13776 TID=24588
LOAD_DLL PID=13776 TID=22388 lpBaseOfDll=00007FFAA2B80000 ucrtbase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x250, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140714448519168)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
CREATE_THREAD PID=13776 TID=19544
LOAD_DLL PID=13776 TID=24588 lpBaseOfDll=00007FFA4F440000 ucrtbase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x25c, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140713048408064)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
warning: MGWHELP: \\?\C:\Windows\System32\krita.dll.debug - not found
warning: MGWHELP: \\?\C:\Windows\System32\.debug\krita.dll.debug - not found
CREATE_THREAD PID=13776 TID=19372
LOAD_DLL PID=13776 TID=24588 lpBaseOfDll=00007FFA4EE20000 ucrtbase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x264, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140713041985536)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
warning: MGWHELP: \\?\C:\Windows\System32\libkritaimage.dll.debug - not found
warning: MGWHELP: \\?\C:\Windows\System32\.debug\libkritaimage.dll.debug - not found
LOAD_DLL PID=13776 TID=19372 lpBaseOfDll=00007FFA67C90000 ucrtbase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x26c, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140713459777536)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb)
Continuing.
warning: MGWHELP: \\?\C:\Windows\System32\libkritaresources.dll.debug - not found
warning: MGWHELP: \\?\C:\Windows\System32\.debug\libkritaresources.dll.debug - not found
LOAD_DLL PID=13776 TID=19544 lpBaseOfDll=00007FFA29D70000 ucrtbase.dll

Thread 1 hit Breakpoint 1, mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x274, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140712420507648)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
240         module->Base = Base;
(gdb) bt
#0  mgwhelp_module_create (process=0x1b0a4b68a10, hFile=0x274, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=140712420507648)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:240
#1  mgwhelp_module_lookup (hProcess=hProcess@entry=0x174, hFile=hFile@entry=0x274, ImageName=ImageName@entry=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", Base=Base@entry=140712420507648)
    at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:361
#2  0x00007ffa606530d3 in MgwSymLoadModuleEx (hProcess=0x174, hFile=0x274, ImageName=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", ModuleName=<optimized out>, BaseOfDll=140712420507648,
    DllSize=262287360, Data=0x0, Flags=0) at D:\dev\krita\drmingw\drmingw\src\mgwhelp/mgwhelp.cpp:472
#3  0x00007ff612883f04 in loadModule (hProcess=0x174, hFile=hFile@entry=0x274, pszImageName=pszImageName@entry=0x5fdd4ff2d0 "\\\\?\\C:\\Windows\\System32\\ucrtbase.dll", lpBaseOfDll=0x7ffa29d70000)
    at D:/dev/krita/drmingw/drmingw/src/common/debugger.cpp:237
#4  0x00007ff612883526 in DebugMainLoop () at D:/dev/krita/drmingw/drmingw/src/common/debugger.cpp:694
#5  0x00007ff6128818d3 in main (argc=4, argv=0x1b0a4b4b810) at D:\dev\krita\drmingw\drmingw\src\catchsegv/catchsegv.cpp:411
(gdb)
@jrfonseca
Copy link
Owner

It shouldn't be difficult to reproduce this, but it would help me to understand where exactly are the binaries. For example, what's the krita.dll and krita.dll.debug's full path?

@jrfonseca
Copy link
Owner

Nevermind, I downloaded krita from https://binary-factory.kde.org/job/Krita_Nightly_Windows_Build/ so I can see all binaries.

However I can't reproduce this. mgwhelp_module_create's ImageName parameter is always correct for me.

It might be something more subtle going on here. Please double check this happens with the released catchsegv.exe or catchsegv.exe built with gcc.

@jrfonseca
Copy link
Owner

@alvinhochun, please rerun catchsegv with -v option, ie, catchsegv.exe -v -m krita.com.

I want to see what's logged on https://github.com/jrfonseca/drmingw/blob/0.9.5/src/common/debugger.cpp#L676-L698

My guess is that GetFileNameFromHandle is somehow returning garbage. Why is not clear, and I can't investigate it furher without reprocuding locally. You'll need to step through GetFileNameFromHandle and see why it's failing.

One potential problem is my abuse of MAX_PATH all over the place. I've been lazy, as I really should start using variable length vectors everywhere for paths, preferably Unicode. But it's time consuming grunt work..

@jrfonseca
Copy link
Owner

Sorry, I see you already run with -v... The relevant message is

 CREATE_PROCESS PID=13776 TID=22388 lpBaseOfImage=00007FF7E4C40000
 
 ...

the expectation would be

 CREATE_PROCESS PID=13776 TID=22388 lpBaseOfImage=00007FF7E4C40000 krita.com
 ...

so this is consistent with GetFileNameFromHandle returning garbage. Why I don't know...

jrfonseca added a commit that referenced this issue Apr 12, 2022
If GetFinalPathNameByHandle fails for reasons other than buffer too
small, the return value is zero, which wasn't being handled properly.

This explains the bogus ImageName seen on
#65

However it's not clear what's the cause for GetFinalPathNameByHandle, or
what can be done about it.
@jrfonseca jrfonseca added the bug label Apr 12, 2022
@jrfonseca
Copy link
Owner

@alvinhochun , ignore all my previous rambles. I think I nailed it in af8adbf. Let me know if the issue persists.

@alvinhochun
Copy link
Contributor Author

Ah, thanks for looking into this. I always forgot to mention that I am using a ramdisk drive created with ImDisk, which often seems to expose some edge cases in applications.

In my case it is still failing to load. A snippet of the debug output:

[19300] GetFinalPathNameByHandle failed with 0x00000001
[19300] MGWHELP: \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\krita.com.debug - not found
[19300] MGWHELP: \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\.debug\krita.com.debug - not found
[19300] GetFinalPathNameByHandle failed with 0x00000001
[19300] MGWHELP: \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\krita.dll.debug - not found
[19300] MGWHELP: \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\.debug\krita.dll.debug - not found

And a snippet of the catchsegv -v output:

CREATE_PROCESS PID=18276 TID=23856 lpBaseOfImage=00007FF7E4C40000 \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\krita.com
LOAD_DLL PID=18276 TID=23856 lpBaseOfDll=00007FFAA4D50000 \\?\C:\Windows\System32\ntdll.dll
LOAD_DLL PID=18276 TID=23856 lpBaseOfDll=00007FFAA3020000 \\?\C:\Windows\System32\kernel32.dll
LOAD_DLL PID=18276 TID=23856 lpBaseOfDll=00007FFAA24F0000 \\?\C:\Windows\System32\KernelBase.dll
CREATE_THREAD PID=18276 TID=10200
LOAD_DLL PID=18276 TID=23856 lpBaseOfDll=00007FFAA2B80000 \\?\C:\Windows\System32\ucrtbase.dll
CREATE_THREAD PID=18276 TID=11020
LOAD_DLL PID=18276 TID=10200 lpBaseOfDll=00007FFA4F440000 \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\krita.dll
CREATE_THREAD PID=18276 TID=24568
LOAD_DLL PID=18276 TID=24568 lpBaseOfDll=00007FFA64150000 \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\libkritaresources.dll
LOAD_DLL PID=18276 TID=10200 lpBaseOfDll=00007FFA4EE20000 \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\libkritaimage.dll
LOAD_DLL PID=18276 TID=24568 lpBaseOfDll=00007FFA62D70000 \Device\ImDisk20\krita-v5.1.0-prealpha-1799-g386dee827c-dirty\bin\libkritaglobal.dll

I think in the case of the path format like \Device\ImDisk20\... it needs some kind of a prefix to get win32 APIs to open it correctly? Maybe something like \\.\? IIRC the same thing also applies to a hard disk volume mounted to a folder mountpoint instead of a drive letter...

@jrfonseca
Copy link
Owner

I think in the case of the path format like \Device\ImDisk20\... it needs some kind of a prefix to get win32 APIs to open it correctly? Maybe something like \\.\?

Yep, GetFileNameFromHandle body needs the rest of the sample code on https://msdn.microsoft.com/en-us/library/aa366789.aspx . I thought it wasn't necessary, but it unmistakably makes a diference on this case.

I'll push a fix after cleaning up the code somewhat.

@jrfonseca jrfonseca reopened this Apr 13, 2022
@alvinhochun
Copy link
Contributor Author

Yay it works! 😄

mstorsjo pushed a commit to llvm/llvm-project that referenced this issue Jun 15, 2022
The WinAPI `GetFinalPathNameByHandle` is used to retrieve the DLL file
name from the HANDLE provided to `LOAD_DLL_DEBUG_EVENT` in the debug
loop. When this API fails, lldb will simply ignore that module.

Certain ramdisk (e.g. ImDisk) does not work with this API, which means
it is impossible to use lldb to debug a process which loads DLLs located
on this type of ramdisk. In order to make this work, we need to use a
fallback routine which involves creating a file mapping, using
`GetMappedFileName` to get a device path, then substitutes the device
path with its drive letter.

References:
* https://developercommunity.visualstudio.com/t/cannot-debug-program-when-compiled-to-ram-drive/43004#T-N109926
* jrfonseca/drmingw#65
* https://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D126657
mem-frob pushed a commit to draperlaboratory/hope-llvm-project that referenced this issue Oct 7, 2022
The WinAPI `GetFinalPathNameByHandle` is used to retrieve the DLL file
name from the HANDLE provided to `LOAD_DLL_DEBUG_EVENT` in the debug
loop. When this API fails, lldb will simply ignore that module.

Certain ramdisk (e.g. ImDisk) does not work with this API, which means
it is impossible to use lldb to debug a process which loads DLLs located
on this type of ramdisk. In order to make this work, we need to use a
fallback routine which involves creating a file mapping, using
`GetMappedFileName` to get a device path, then substitutes the device
path with its drive letter.

References:
* https://developercommunity.visualstudio.com/t/cannot-debug-program-when-compiled-to-ram-drive/43004#T-N109926
* jrfonseca/drmingw#65
* https://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D126657
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants