How to know which function called this...

Started by
16 comments, last by Prozak 20 years, 2 months ago
Code to do a stack trace:Link. It resolves addresses to function name and gives name, type, and value of all parameters/local variables.
How are you walking the stack? You can''t rely on the frame pointer (often optimized away in release builds), and need to take care when following the return address (the jump to your function may have been relative, as opposed to the normal 0xe8 32 bit call instruction; it may also have been to a trampoline which in turn calls you).
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
Advertisement
I traverse the stack by looking at "ebp". Ive understood how the values are arranged in memory.

The code is completed, if anyone finds interest in it ill paste it here...

Jester Says: Visit Positronic Dreams![Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."
Ok, I need help with another thing here, I have:

UINT buf[100];
void StackFill(void * StackBuffer)
{
__asm
{
mov [buf+ebp], eax (a)
mov [StackBuffer+ebp], eax (b)
(...)

So thats my function that fills a buffer with the stack trace.

"buf" is a global variable, for testing purposes.
What I need to do now is pass the address of a buffer to the function, name StackBuffer, and use that variable instead of "buf" in the code.

But when i run (b) it fails...

What is the correct way of writing to the address that StackBuffer points to?

Thanks for any tips on this...

Jester Says: Visit Positronic Dreams![Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It's the only way to be sure."

[edited by - pentium3id on February 7, 2004 3:25:43 PM]
anyone?

Jester Says: Visit Positronic Dreams![Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."
Look for the "Debug Help Library" that comes with the Microsoft Platform SDK. StackWalk64 () may be a starting point.
I have writing the stack walking code already, just neet it to accept as a parameter a pointer to a buffer that will be filled with the stack trace...

Having trouble with the asm code in that dptm....

Jester Says: Visit Positronic Dreams![Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It''s the only way to be sure."
ah, the frame pointer method. Doesn''t work if the compiler decides to optimize away the stack frame, which it will in release mode. VC writes out FPO (FP Omission) data to compensate, which is read by StackWalk[64]. If you insist on doing it yourself (which is at least educational and makes things portable to IA32 \ Win32), accept that it will only work in debug mode, or follow the return address. As mentioned, to do that reliably, you have to cover a lot of cases. I remember seeing the source for StackWalk a long time ago (MS published it as a sample, IIRC) - see if you can find that.

To get the pointer you pass in, [StackBuffer], you need to deference StackBuffer (without brackets = label, resolves to address of the variable; with = contents of the address in brackets). mov ebx, [StackBuffer]. The value of ebx is now the address of your buffer; you will use it as a pointer. Now write mem from source address ebp+index to dest array ebx+index: mov eax, [ebp+ecx]
mov [ebx+ecx], eax
add ecx, byte 4 ; hehe, habit. MASM (the inline assembler) does the byte part automatically, so leave it out.
note: IA32 can''t do memory to memory transfers - you have to read it into a register.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
Well, heres the code in case anybody else than just me finds it usefull:
/**///oo-ooooooo-ooooooo-ooooooo-ooooooo-ooooooo[Function     ]-[StackFill    ]void  StackFill(void * StackBuffer){__asm{		push ebp		push eax			// Stack Trace Value		push ebx			// Next Pointer		push ecx			// Last Stack Trace value		push edx			// Original ESP Value		mov edx, esp		mov ecx, StackBuffer		mov esp, ebp		xor ebp, ebpstart1:		pop ebx				// next pointer		pop eax				// stack trace value		mov esp, ebx		// Setup our next loop		mov [ecx+ ebp], eax		add ebp, 4		cmp ebx, edx		jb end1		cmp eax, 0		je end1		cmp ebx, 0		je end1		jmp start1end1:		mov eax, ebp		// Saves How many Steps		shr eax, 2		dec eax		dec eax		mov [ecx], eax		// Undo		mov esp, edx		pop edx		pop ecx		pop ebx		pop eax		pop ebp};};//ExampleUINT       StackBuf[100];StackFill(&StackBuf);
Helped me trace back to a damn leak which was really hard to pinpoint... its here for GameDev posterity and general flaming, lol....

Edit: Note: Position 0 (zero) on the target buffer to be filled with the traces, will hold the number of traces, so your first trace address is in StackBuf[1]...Jester Says: Visit Positronic Dreams![Hugo Ferreira][Positronic Dreams][Colibri 3D Engine][Entropy HL2 MOD]
[Yann L.][Enginuity] [Penny Arcade] [MSDN][VS RoadMap][Humus][BSPs][UGP][NeHe]
"I say we take off and nuke the entire site from orbit. It's the only way to be sure."

[edited by - pentium3id on February 7, 2004 10:48:10 PM]

This topic is closed to new replies.

Advertisement