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).
How to know which function called this...
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...
[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."
The code is completed, if anyone finds interest in it ill paste it here...
[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...
[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]
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...
[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?
[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."
[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....
[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."
Having trouble with the asm code in that dptm....
[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.
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.
Well, heres the code in case anybody else than just me finds it usefull:
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]...[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]
/**///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]...[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
Popular Topics
Advertisement