Skip to content

Conversation

@NicoleFaye
Copy link

@NicoleFaye NicoleFaye commented Jan 19, 2026

Added time range filter for ttd code coverage analysis.
Adjusted code coverage highlight alpha 1/4 -> 2/3
Fixed info log being incorrectly written to error stream for saving cached analysis results.
Added gitignore entries for windows build related artifacts

First time contributing to the repo. I vaguely understand there is an agreement i may need to sign if the code is accepted.

Let me know if there is anything i can do to improve this PR for future reference/contribution.

fixes #960 #966 #967 #968

@CLAassistant
Copy link

CLAassistant commented Jan 19, 2026

CLA assistant check
All committers have signed the CLA.

@xusheng6
Copy link
Member

Hi @NicoleFaye , thanks a lot for the PR. This looks like a nice addition, I will review it when I can

@xusheng6 xusheng6 self-requested a review January 19, 2026 06:28
@NicoleFaye
Copy link
Author

NicoleFaye commented Jan 19, 2026

upon further examination. it seems like it might be more appropriate to implement a call to
dx @$cursession.TTD.MemoryForPositionRange(startAddress, endAddress, "accessType", minPosition, maxPosition)

instead of manually filtering time positions on a generic memory query.

I can implement a change in logic, but wanted to add this comment before then.

My main concern with this possible change would be it's not generic enough to work with time travel debuggers other than windbg, I haven't looked too deeply at how the adapters work. or if this coverage analysis is specific to windbg.

@xusheng6
Copy link
Member

upon further examination. it seems like it might be more appropriate to implement a call to dx @$cursession.TTD.MemoryForPositionRange(startAddress, endAddress, "accessType", minPosition, maxPosition)

instead of manually filtering time positions on a generic memory query.

I can implement a change in logic, but wanted to add this comment before then.

My main concern with this possible change would be it's not generic enough to work with time travel debuggers other than windbg, I haven't looked too deeply at how the adapters work. or if this coverage analysis is specific to windbg.

I think this is fantastic idea!

Also I would ask you to kindly test to make sure MemoryForPositionRange actually limits the query range rather than just filter it. The way to test is to get a reasonably large trace, and run the same query with and without a time range (ideally the time range is small). Expect the one with a time range runs much faster. Note you need to totally reset the debugger (close binja/windbg) because the query results are cached, and that would surely affect the accuracy of the comparison

Once you get that API, if you feel like to, you could also switch this dialog to use the new API:

image

You probably want to move the start/end address to the same line, and add a new start/end time beneath it

@xusheng6
Copy link
Member

Please also create a separate issue to track the other enhancements made in this PR, which helps us better keep track of things!

@NicoleFaye NicoleFaye marked this pull request as draft January 21, 2026 06:18
@NicoleFaye
Copy link
Author

Also I would ask you to kindly test to make sure MemoryForPositionRange actually limits the query range rather than just filter it. The way to test is to get a reasonably large trace, and run the same query with and without a time range (ideally the time range is small). Expect the one with a time range runs much faster. Note you need to totally reset the debugger (close binja/windbg) because the query results are cached, and that would surely affect the accuracy of the comparison

It indeed does. I just tested with a larger trace ~20gb, just as you described here.

@NicoleFaye
Copy link
Author

I have implemented the call to MemoryForPositionRange in the dbgeng adapter and then added that call to the Code Coverage call in place of the filtering i originally implemented.

I am going to keep this PR as a draft until i can do a little more testing to make sure the ui parses correctly.

Then i will see about using this new api in the TTD memory query window as well. Once that has been completed i will take the PR out of draft to be reviewed. :)

@xusheng6
Copy link
Member

Also I would ask you to kindly test to make sure MemoryForPositionRange actually limits the query range rather than just filter it. The way to test is to get a reasonably large trace, and run the same query with and without a time range (ideally the time range is small). Expect the one with a time range runs much faster. Note you need to totally reset the debugger (close binja/windbg) because the query results are cached, and that would surely affect the accuracy of the comparison

It indeed does. I just tested with a larger trace ~20gb, just as you described here.

That is fantastic!

@xusheng6
Copy link
Member

I have implemented the call to MemoryForPositionRange in the dbgeng adapter and then added that call to the Code Coverage call in place of the filtering i originally implemented.

I am going to keep this PR as a draft until i can do a little more testing to make sure the ui parses correctly.

Then i will see about using this new api in the TTD memory query window as well. Once that has been completed i will take the PR out of draft to be reviewed. :)

Sounds good, please ping me when you are done with it!

@NicoleFaye NicoleFaye force-pushed the TTDCodeCoverageTimeRange branch from 0390cf4 to 6e2fdfc Compare January 22, 2026 17:39
@NicoleFaye
Copy link
Author

@xusheng6 I implemented the change in api for the TTD memory widget, but basically TTD.Memory and TTD.MemoryForPositionRange return different structs and TTD.MemoryForPositionRange has (as far as i can tell) an undocumented return type.

Here is an example of what i mean by that:

>>> dx -r1 @$cursession.TTD.Memory(0x7ff74e769e70, 0x7ff74e769e80, "e").First()
@$cursession.TTD.Memory(0x7ff74e769e70, 0x7ff74e769e80, "e").First()
    EventType        : 0x1
    ThreadId         : 0x9bd8
    UniqueThreadId   : 0x1e
    TimeStart        : 2B65:21B
    TimeEnd          : 2B65:21B
    AccessType       : Execute
    IP               : 0x7ff74e769e70
    Address          : 0x7ff74e769e70
    Size             : 0x2
    Value            : 0x5540
    SystemTimeStart  : Saturday, January 17, 2026 05:58:34.140
    SystemTimeEnd    : Saturday, January 17, 2026 05:58:34.140
>>> dx -r1 @$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e" , "0:0","adf1:745").First()
@$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e" , "0:0","adf1:745").First()
    Position         : 2B65:21B
    ThreadId         : 0x9bd8
    UniqueThreadId   : 0x1e
    Address          : 0x7ff74e769e70
    IP               : 0x7ff74e769e70
    Size             : 0x2
    AccessType       : Execute
    Value            : 0x4154415756535540
    Data             
>>> dx @$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e", "0:0", "adf1:745").First().Data
@$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e", "0:0", "adf1:745").First().Data
    [0x0]            : 0x40
    [0x1]            : 0x55
    [0x2]            : 0x53
    [0x3]            : 0x56
    [0x4]            : 0x57
    [0x5]            : 0x41
    [0x6]            : 0x54
    [0x7]            : 0x41

So i created the type TTDPositionRangeIndexedMemoryEvent, not really thrilled about the name but wasnt really sure what else to call it. I have updated the TTDMemoryWidget to use this new api, it changes the output table a bit so i adjusted it to the new event format.

I also have a comment in there regarding the undocumented event type, so its still a little messy in the source but wanted to explain why i added the type. I still see this as a draft but i think its in a spot for you to take a peek and see if its something you want to move forward with as the approach.
image

@xusheng6
Copy link
Member

xusheng6 commented Jan 23, 2026

@xusheng6 I implemented the change in api for the TTD memory widget, but basically TTD.Memory and TTD.MemoryForPositionRange return different structs and TTD.MemoryForPositionRange has (as far as i can tell) an undocumented return type.

Here is an example of what i mean by that:

>>> dx -r1 @$cursession.TTD.Memory(0x7ff74e769e70, 0x7ff74e769e80, "e").First()
@$cursession.TTD.Memory(0x7ff74e769e70, 0x7ff74e769e80, "e").First()
    EventType        : 0x1
    ThreadId         : 0x9bd8
    UniqueThreadId   : 0x1e
    TimeStart        : 2B65:21B
    TimeEnd          : 2B65:21B
    AccessType       : Execute
    IP               : 0x7ff74e769e70
    Address          : 0x7ff74e769e70
    Size             : 0x2
    Value            : 0x5540
    SystemTimeStart  : Saturday, January 17, 2026 05:58:34.140
    SystemTimeEnd    : Saturday, January 17, 2026 05:58:34.140
>>> dx -r1 @$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e" , "0:0","adf1:745").First()
@$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e" , "0:0","adf1:745").First()
    Position         : 2B65:21B
    ThreadId         : 0x9bd8
    UniqueThreadId   : 0x1e
    Address          : 0x7ff74e769e70
    IP               : 0x7ff74e769e70
    Size             : 0x2
    AccessType       : Execute
    Value            : 0x4154415756535540
    Data             
>>> dx @$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e", "0:0", "adf1:745").First().Data
@$cursession.TTD.MemoryForPositionRange(0x7ff74e769e70, 0x7ff74e769e80, "e", "0:0", "adf1:745").First().Data
    [0x0]            : 0x40
    [0x1]            : 0x55
    [0x2]            : 0x53
    [0x3]            : 0x56
    [0x4]            : 0x57
    [0x5]            : 0x41
    [0x6]            : 0x54
    [0x7]            : 0x41

So i created the type TTDPositionRangeIndexedMemoryEvent, not really thrilled about the name but wasnt really sure what else to call it. I have updated the TTDMemoryWidget to use this new api, it changes the output table a bit so i adjusted it to the new event format.

I also have a comment in there regarding the undocumented event type, so its still a little messy in the source but wanted to explain why i added the type. I still see this as a draft but i think its in a spot for you to take a peek and see if its something you want to move forward with as the approach. image

Thanks for the swift progress!

  1. Nice job digging into the difference between MemoryForPositionRange and Memory. I think the difference is fine, we still have most of the useful things that we need. Regarding the difference on the value, I think this is a bug on the Microsoft side, but you can keep it as such and I will decide if we wan to truncate it, and if so, at where.
  2. I looked at the code and it is very well-written. This definitely makes my life easier, thanks!
  3. I am curious why you decided to make the highlight color's alpha at 170? If I were to do it, I will probably set it to 255. I am not sure if you tested it and find that value the best

Please take you time to polish it. Once you are done with it, please let me know and I will review it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TTD coverage highlight is not super obvious to see

3 participants