@@ -47,13 +47,79 @@ func TestCallstack(t *testing.T) {
4747
4848 uframe := callstack .FinalUserFrame ()
4949 require .NotNil (t , uframe )
50- assert .Equal (t , "7ffb5c1d0396 " , uframe .Addr .String ())
51- assert .Equal (t , "CreateProcessW " , uframe .Symbol )
52- assert .Equal (t , "C:\\ WINDOWS \\ System32 \\ KERNELBASE .dll" , uframe .Module )
50+ assert .Equal (t , "7ffb3138592e " , uframe .Addr .String ())
51+ assert .Equal (t , "Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly " , uframe .Symbol )
52+ assert .Equal (t , "C:\\ Program Files \\ JetBrains \\ GoLand 2021.2.3 \\ jbr \\ bin \\ java .dll" , uframe .Module )
5353
5454 kframe := callstack .FinalKernelFrame ()
5555 require .NotNil (t , kframe )
5656 assert .Equal (t , "fffff8015690b644" , kframe .Addr .String ())
5757 assert .Equal (t , "ObDeleteCapturedInsertInfo" , kframe .Symbol )
5858 assert .Equal (t , "C:\\ WINDOWS\\ system32\\ ntoskrnl.exe" , kframe .Module )
5959}
60+
61+ func TestCallstackFinalUserFrame (t * testing.T ) {
62+ var tests = []struct {
63+ callstack Callstack
64+ expectedMod string
65+ expectedSym string
66+ }{
67+ {callstack : callstackFromFrames (
68+ Frame {Addr : 0xf259de , Module : unbacked , Symbol : "?" },
69+ Frame {Addr : 0x7ffe4fda6e3b , Module : "C:\\ Windows\\ System32\\ KernelBase.dll" , Symbol : "SetThreadContext" },
70+ Frame {Addr : 0x7ffe52942b24 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "ZwSetContextThread" },
71+ Frame {Addr : 0xfffff807e228c555 , Module : "C:\\ WINDOWS\\ system32\\ ntoskrnl.exe" , Symbol : "setjmpex" },
72+ Frame {Addr : 0xfffff807e264805c , Module : "C:\\ WINDOWS\\ system32\\ ntoskrnl.exe" , Symbol : "ObOpenObjectByPointerWithTag" }),
73+ expectedMod : "unbacked" ,
74+ expectedSym : "?" ,
75+ },
76+ {callstack : callstackFromFrames (
77+ Frame {Addr : 0x7ffff0f3bf6c , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "RtlUserThreadStart" },
78+ Frame {Addr : 0x7ffff03ee8d7 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "BaseThreadInitThunk" },
79+ Frame {Addr : 0x7ffff0ee5f13 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "TpCallbackMayRunLong" },
80+ Frame {Addr : 0x7ffff0c78788 , Module : "C:\\ Windows\\ System32\\ rpcrt4.dll" , Symbol : "RpcGetBufferWithObject" },
81+ Frame {Addr : 0x7ffff0c797e3 , Module : "C:\\ Windows\\ System32\\ rpcrt4.dll" , Symbol : "RpcImpersonateClient" },
82+ Frame {Addr : 0x7fffee58d16a , Module : "C:\\ Windows\\ System32\\ KernelBase.dll" , Symbol : "CreateProcessInternalW" },
83+ Frame {Addr : 0x7ffff0fe1204 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "ZwCreateUserProcess" }),
84+ expectedMod : "C:\\ Windows\\ System32\\ rpcrt4.dll" ,
85+ expectedSym : "RpcImpersonateClient" ,
86+ },
87+ {callstack : callstackFromFrames (
88+ Frame {Addr : 0x7fffa7e3bf6c , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "RtlUserThreadStart" },
89+ Frame {Addr : 0x7fffa60de8d7 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "BaseThreadInitThunk" },
90+ Frame {Addr : 0x7ff6163cfc68 , Module : "C:\\ Program Files\\ Mozilla Firefox\\ firefox.exe" , Symbol : "TargetCreateThread" },
91+ Frame {Addr : 0x7fffee58d16a , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "ZwMapViewOfSection" },
92+ Frame {Addr : 0xfffff8028deeed1d , Module : "C:\\ WINDOWS\\ system32\\ ntoskrnl.exe" , Symbol : "NtMapViewOfSection" }),
93+ expectedMod : "C:\\ Program Files\\ Mozilla Firefox\\ firefox.exe" ,
94+ expectedSym : "TargetCreateThread" ,
95+ },
96+ {callstack : callstackFromFrames (
97+ Frame {Addr : 0x7fffa7e3bf6c , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "RtlUserThreadStart" },
98+ Frame {Addr : 0x7fffa60de8d7 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "BaseThreadInitThunk" },
99+ Frame {Addr : 0x7ffff0c78788 , Module : "C:\\ Windows\\ System32\\ rpcrt4.dll" , Symbol : "NdrServerCallNdr64" },
100+ Frame {Addr : 0x7ffff0c574ed , Module : "C:\\ Windows\\ System32\\ rpcrt4.dll" , Symbol : "NdrStubCall2" },
101+ Frame {Addr : 0x7ffff03fb090 , Module : "C:\\ Windows\\ System32\\ kernel32.dll" , Symbol : "CreateProcessInternalW" },
102+ Frame {Addr : 0x7fffee58a923 , Module : "C:\\ Windows\\ System32\\ kernel32.dll" , Symbol : "CreateProcessAsUserW" },
103+ Frame {Addr : 0x7ffff0fe1204 , Module : "C:\\ Windows\\ System32\\ ntdll.dll" , Symbol : "ZwCreateUserProcess" }),
104+ expectedMod : "C:\\ Windows\\ System32\\ rpcrt4.dll" ,
105+ expectedSym : "NdrStubCall2" ,
106+ },
107+ }
108+
109+ for _ , tt := range tests {
110+ t .Run (tt .expectedMod + "!" + tt .expectedSym , func (t * testing.T ) {
111+ f := tt .callstack .FinalUserFrame ()
112+ require .NotNil (t , f )
113+ assert .Equal (t , tt .expectedMod , f .Module )
114+ assert .Equal (t , tt .expectedSym , f .Symbol )
115+ })
116+ }
117+ }
118+
119+ func callstackFromFrames (frames ... Frame ) Callstack {
120+ var c Callstack
121+ for _ , frame := range frames {
122+ c .PushFrame (frame )
123+ }
124+ return c
125+ }
0 commit comments