Ryan Fleury's banner
Ryan Fleury's profile picture

Ryan Fleury

@rfleury23,352 subscribers

RJF // @dgtlgrove // Making RAD Debugger at @radgametools in @epicgames (opinions my own)

Shorts

This is a huge bang-for-buck improvement you can add to your UIs.

This is a huge bang-for-buck improvement you can add to your UIs.

157,126 Aufrufe

In RADDBG, the "Step Out" command has been upgraded to support block stepping! It now lets you step through blocks, out of loops, or (the traditional behavior) out of function frames.

In RADDBG, the "Step Out" command has been upgraded to support block stepping! It now lets you step through blocks, out of loops, or (the traditional behavior) out of function frames.

27,672 Aufrufe

Almost fully ported the renderer to OpenGL during the last bit of the day This is not for Windows

Almost fully ported the renderer to OpenGL during the last bit of the day This is not for Windows

30,974 Aufrufe

Huge upgrade to loading speeds coming soon, especially with DLL-heavy codebases like UE! The primary reason PDB -> RDI conversion (or PDB parsing in debuggers more generally) is a big bottleneck in startup time is because they must be converted/parsed/loaded _serially_. This may seem surprising, since intuitively it'd seem like they can be converted/parsed/loaded/etc. in parallel. This is not true in the general case due to breakpoints, and how they relate to an API like `LoadLibrary`, and how it translates into debug events. When a debuggee runs `LoadLibrary`, the debugger will receive a debug event informing the debugger that the associated module was loaded. Any time a debug event is sent to the debugger, the debuggee stops running entirely. This is so that the debugger can make decisions about how the debuggee should proceed. For example, if I have a breakpoint on `foo.c:123`, that file name and line number can only be correctly interpreted (meaning resolved into code addresses) using debug information. The debugger only knows about that debug information from the PDB - without it, that file/line combo is meaningless. But importantly, the debugger cannot *resume* the debuggee until it has resolved that breakpoint - otherwise the debuggee may execute code which *would've* hit the breakpoint, *if* it were resolved in time. So, the debugger needs to ensure that all breakpoints are fully resolved before resuming. This is a correctness detail that everyone has to pay for, basically because `LoadLibrary`s are received one-at-a-time. Obviously, if it were instead an API like `LoadLibraries`, then the debugger could prepare all of the debug info in one batch before resuming - but it doesn't know what that batch would be, given just an initial `LoadLibrary`. This is unfortunate, because *generally* you are not debugging the code loading a bunch of DLLs, but the debugger can't really know that. (It is probably a good idea to provide a `raddbg_load_libraries` API at some point, so that we can resolve this issue on the debuggee side). In any case, RADDBG now resolves breakpoints much more quickly by avoiding 99% of debug info conversion work to do a common case of breakpoint resolution - you might call this "breakpoint disqualification". Basically, if a breakpoint is set, and we can quickly determine that that breakpoint's information (file location, expression, condition, etc.) *cannot apply* to some module's debug info - more quickly than doing a *full* PDB -> RDI conversion (which entails a full parse & a bunch of work) - then we can simplify the very common case in DLL-heavy cases: you put a breakpoint on `foo.c:123`, when 99% of the DLLs do not have any line info for that file, so the debugger can resume *knowing* that breakpoint will not resolve within that file. In this demo video, you can see I place a breakpoint that only resolves within the executable's debug info - it does not resolve within any of the 100 DLLs that are loaded serially. Within the `Modules` tab, you can see that as I run the target, most of the debug info is not loaded initially, even though the debuggee is running. That debug info is loading in parallel, as the debugger knows it does not need to wait for that debug info to be prepared for this breakpoint.

Huge upgrade to loading speeds coming soon, especially with DLL-heavy codebases like UE! The primary reason PDB -> RDI conversion (or PDB parsing in debuggers more generally) is a big bottleneck in startup time is because they must be converted/parsed/loaded _serially_. This may seem surprising, since intuitively it'd seem like they can be converted/parsed/loaded/etc. in parallel. This is not true in the general case due to breakpoints, and how they relate to an API like `LoadLibrary`, and how it translates into debug events. When a debuggee runs `LoadLibrary`, the debugger will receive a debug event informing the debugger that the associated module was loaded. Any time a debug event is sent to the debugger, the debuggee stops running entirely. This is so that the debugger can make decisions about how the debuggee should proceed. For example, if I have a breakpoint on `foo.c:123`, that file name and line number can only be correctly interpreted (meaning resolved into code addresses) using debug information. The debugger only knows about that debug information from the PDB - without it, that file/line combo is meaningless. But importantly, the debugger cannot *resume* the debuggee until it has resolved that breakpoint - otherwise the debuggee may execute code which *would've* hit the breakpoint, *if* it were resolved in time. So, the debugger needs to ensure that all breakpoints are fully resolved before resuming. This is a correctness detail that everyone has to pay for, basically because `LoadLibrary`s are received one-at-a-time. Obviously, if it were instead an API like `LoadLibraries`, then the debugger could prepare all of the debug info in one batch before resuming - but it doesn't know what that batch would be, given just an initial `LoadLibrary`. This is unfortunate, because *generally* you are not debugging the code loading a bunch of DLLs, but the debugger can't really know that. (It is probably a good idea to provide a `raddbg_load_libraries` API at some point, so that we can resolve this issue on the debuggee side). In any case, RADDBG now resolves breakpoints much more quickly by avoiding 99% of debug info conversion work to do a common case of breakpoint resolution - you might call this "breakpoint disqualification". Basically, if a breakpoint is set, and we can quickly determine that that breakpoint's information (file location, expression, condition, etc.) *cannot apply* to some module's debug info - more quickly than doing a *full* PDB -> RDI conversion (which entails a full parse & a bunch of work) - then we can simplify the very common case in DLL-heavy cases: you put a breakpoint on `foo.c:123`, when 99% of the DLLs do not have any line info for that file, so the debugger can resume *knowing* that breakpoint will not resolve within that file. In this demo video, you can see I place a breakpoint that only resolves within the executable's debug info - it does not resolve within any of the 100 DLLs that are loaded serially. Within the `Modules` tab, you can see that as I run the target, most of the debug info is not loaded initially, even though the debuggee is running. That debug info is loading in parallel, as the debugger knows it does not need to wait for that debug info to be prepared for this breakpoint.

17,527 Aufrufe

Videos

rfleury's profile picture

This is not a real company

Ryan Fleury

4,418,947 Aufrufe • vor 5 Monaten

rfleury's profile picture

More excellence

Ryan Fleury

182,604 Aufrufe • vor 5 Monaten

rfleury's profile picture

Scope ending annotations

Ryan Fleury

14,164 Aufrufe • vor 22 Tagen

rfleury's profile picture

On the deletion of accounts

Ryan Fleury

23,648 Aufrufe • vor 1 Monat

rfleury's profile picture

Getting closer.

Ryan Fleury

76,195 Aufrufe • vor 6 Monaten

rfleury's profile picture

Breakpoint syncing progress

Ryan Fleury

27,166 Aufrufe • vor 11 Monaten