Stack backtrace stopping

Debugging a full memory dump, I have a thread call stack that windbg doesn’t walk back completely.

It stops from walking back the stack after some point.

0: kd> k
*** Stack trace for last set context - .thread/.cxr resets it

Child-SP RetAddr Call Site

00 fffffe884ee576e0 fffff80680ac7260 nt!KiSwapContext+0x76
01 fffffe884ee57820 fffff80680ac678f nt!KiSwapThread+0x500
02 fffffe884ee578d0 fffff80680a56c54 nt!KiCommitThreadWait+0x14f
03 fffffe884ee57970 fffff80680e1a7d0 nt!KeWaitForAlertByThreadId+0xc4
04 fffffe884ee579d0 fffff80680c11505 nt!NtWaitForAlertByThreadId+0x30
05 fffffe884ee57a00 00007ffa4d170fd4 nt!KiSystemServiceCopyEnd+0x25
06 000000ef3b8ff9c8 00007ffa4d134d6d ntdll!NtWaitForAlertByThreadId+0x14
07 000000ef3b8ff9d0 00007ffa4d134c22 ntdll!RtlpWaitOnAddressWithTimeout+0x81
08 000000ef3b8ffa00 00007ffa4d134a3d ntdll!RtlpWaitOnAddress+0xae
09 000000ef3b8ffa70 00007ffa4d0ffcb4 ntdll!RtlpWaitOnCriticalSection+0xfd
0a 000000ef3b8ffb50 00007ffa4d0ffae2 ntdll!RtlpEnterCriticalSectionContended+0x1c4
0b 000000ef3b8ffbb0 00007ff70b1f5c88 ntdll!RtlEnterCriticalSection+0x42
0c 000000ef3b8ffbe0 0000000000000000 XXX!YYY::ZZZ+0x28 [filepath @ 308]

I can do the back walking by myself without difficulty.

The code of the function to know where the next RIP on the stack will be is easy to process, windbg needs to add 0x20+8+8 (sub rsp,20h+pushed rbx+RIP pushed), here is the function :

XXX!YYY::ZZZ:
00007ff70b1f5c60 4053            push    rbx
00007ff70b1f5c62 4883ec20        sub     rsp,20h
00007ff70b1f5c66 803d94a9220000  cmp     byte ptr [XXX!AAA (00007ff70b420601)],0
00007ff70b1f5c6d 488bd9          mov     rbx,rcx 
00007ff70b1f5c70 740c            je      XXX!YYY::BBB+0x1e (00007ff70b1f5c7e) 
00007ff70b1f5c72 83faff          cmp     edx,0FFFFFFFFh
00007ff70b1f5c75 7407            je      XXX!YYY::BBB+0x1e (00007ff70b1f5c7e)
00007ff70b1f5c77 33c9            xor     ecx,ecx 
00007ff70b1f5c79 e8e21c0100      call    XXX!CCC (00007ff70b207960) 
00007ff70b1f5c7e 488d4b08        lea     rcx,[rbx+8]
00007ff70b1f5c82 ff15d0fa1a00    call    qword ptr [XXX!_imp_EnterCriticalSection (00007ff70b3a5758)]
00007ff70b1f5c88 33c0            xor     eax,eax 
00007ff70b1f5c8a 4883c420        add     rsp,20h
00007ff70b1f5c8e 5b              pop     rbx
00007ff70b1f5c8f c3              ret

So why is it failing ? How can I know what is it missing ?

The call that led to XXX!YYY::ZZZ was a call qword ptr [rax]

Even if I use kL = calculated_RSP saved_RIP on the subsequent frames, I still fails.

The usual cause is that the unwind data for the function is paged out. What does:

.fnent XXX!YYY::ZZZ

Say? You might be able to get the stack walk to work if you have a copy of the binary locally and set your image search path to point to it. I don’t have a case to try this locally at the moment but I know it’s worked for me in the past.

Thank you for your answer Scott.

The usual cause is that the unwind data for the function is paged out.

I think you are right.

!dh on my module helps me find the Exception direction offset.

0: kd> !dh XXX 

[...] 

233000 [   16020] address [size] of Exception Directory 

[...]

If I try to see the memory content at that location, I get interrogation marks.

0: kd> dd XXX+233000
00007ff70b423000  ???????? ???????? ???????? ???????? 

00007ff70b423010  ???????? ???????? ???????? ????????
00007ff70b423020  ???????? ???????? ???????? ???????? 

00007ff70b423030  ???????? ???????? ???????? ????????
00007ff70b423040  ???????? ???????? ???????? ???????? 

00007ff70b423050  ???????? ???????? ???????? ????????
00007ff70b423060  ???????? ???????? ???????? ???????? 

00007ff70b423070  ???????? ???????? ???????? ????????

Then looking at !pte tells me that PTE is not valid.

0: kd> !pte 00007ff7`0b423000 

VA 00007ff70b423000 

PXE at FFFFEFF7FBFDF7F8    PPE at FFFFEFF7FBEFFEE0    PDE at FFFFEFF7DFFDC2D0    PTE at FFFFEFBFFB85A118 

contains 0A0000040389D867  contains 0A0000026309E867  contains 0A00000333FA1867  contains 0000000000000000 

pfn 40389d    ---DA--UWEV  pfn 26309e    ---DA--UWEV  pfn 333fa1    ---DA--UWEV  not valid

Source : This article helped me Writing a Debugger From Scratch - DbgRs Part 6 - Stacks // TimDbg

I tought that windbg would say it when these information are not available : Stack Unwind Information Not Available - Windows drivers | Microsoft Learn

But It’s not telling me anything, do you have any idea why ?

Also is there another way to force windbg to guess the pushed RSP and RIP location of the stack, so that is can have another way of finding the frames ?

You got that error on the x86 when you didn’t have PDBs with FPO information. Not sure why they didn’t port the error when stack walking on the x64/ARM but they didn’t so you’ll never see it.

Also is there another way to force windbg to guess the pushed RSP and RIP location of the stack, so that is can have another way of finding the frames ?

Feeding the addresses into the k command is the only way. But that again uses the unwind data so it will keep failing to resolve the stack until you get to a series of frames with valid unwind data.

Did you try setting the executable search path?