Archived

This topic is now archived and is closed to further replies.

How to know which function called this...

This topic is 5092 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im trying to trace back, and do some debugging. I want to know who allocates a certain resource in my engine, cause it isnt geting deallocated... So, i could just copy a portion of the stack somewhere, and dump it right? No problems there I guess, but how do I know that 0x45FFAD2B is the address of my SQRT function (just examples) Is there some form of MACRO or shortcut in can use under Visual Studio to know and link an address to a function or class method? 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."

Share this post


Link to post
Share on other sites
Currently using this simple code to copy the stack to a temporary buffer, so that i can analise it later...
void * buf[100]; // Any 4 byte type will do


//ooooooooooooooooooooooooooooooooo

void jump_b(void)
{
void* _esp;

__asm
{
mov _esp, esp
};

memcpy(buf, _esp, 100);


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 11:55:57 AM]

Share this post


Link to post
Share on other sites
If you''re using MSVC, then enter the debugger, put a breakpoint in the function you want to know the parent of, and run to that breakpoint. In the lower left-hand corner, there should be a box that lists some variables and stuff, and it should have a few tabs at the bottom that say "Auto", "Locals", and "this". At the top of that box is a combo box that says "Context", and the current function prototype should be listed. Clicking the combo box will give you a complete list of the current function stack with full prototypes, and by selecting one, it will take you to the exact point in your source (or disassembly if it''s a system function) where your function was called.

Share this post


Link to post
Share on other sites
Thanks Aprosenf, but thats not what i want.

There are thousands of places in my code where a Resource might get created, and if that same resource never gets de-allocated, I need to trace which function/class allocated it.

So, i''m attaching a stack trace to each resource, so that I can, at the end of the program, see which resources werent deallocated, and why...

The "Call Stack" window doesnt help me because, although i can breakpoint into the code each time a resource is created, at that point i dont know if it will be deallocated correctly, and theres no point in putting a breakpoint on the destructor, because it doesnt get called for non-deallocated resources..

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."

Share this post


Link to post
Share on other sites
Wouldn''t it just be easier to use the __FUNCTION__, __FILE__ and __LINE__ macros rather than messing with the stack dump?

Share this post


Link to post
Share on other sites
quote:
Wouldn''t it just be easier to use the __FUNCTION__, __FILE__ and __LINE__ macros


I use this for a lot of my debugging... build in additional parameters in the CreateResource() type function that includes the above macros..

Or simply give it a unique ID number that you can track (combine this with a log file and you''re sorted).

That way, when you detect your leak, you output its ID and/or macros; that way you should be able to pinpoint the culprit

hth
Jack

Share this post


Link to post
Share on other sites
quote:
Wouldn''t it just be easier to use the __FUNCTION__, __FILE__ and __LINE__ macros rather than messing with the stack dump?
Correct me if i''m wrong, but doesnt that tell us where we are now? I want to know what function called us, so...

The stack trace tool im doing, if done right will also allows me to trace back from dlls, etc, which that cant do...


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."

Share this post


Link to post
Share on other sites
quote:
Original post by pentium3id
quote:
Wouldn''t it just be easier to use the __FUNCTION__, __FILE__ and __LINE__ macros rather than messing with the stack dump?
Correct me if i''m wrong, but doesnt that tell us where we are now? I want to know what function called us, so...
So record where we are when we''re created. C++ isn''t introspective.

Share this post


Link to post
Share on other sites
What if I want to know who called my caller?

This would lead to either a lot of code change or a mess of macros...

The Stack Trace code is almost finished anyway, maybe i''ll do a short Article for GameDev...

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."

Share this post


Link to post
Share on other sites
Thats going to be impossible to read once name mangling gets ahold of it. Look up StackWalk64 in MSDN.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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."

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Look for the "Debug Help Library" that comes with the Microsoft Platform SDK. StackWalk64 () may be a starting point.

Share this post


Link to post
Share on other sites
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."

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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, ebp
start1:
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 start1
end1:
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
};

};


//Example

UINT 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]

Share this post


Link to post
Share on other sites