Recent

Author Topic: Getting Caller function or Procedure.  (Read 2322 times)

jamie

  • Hero Member
  • *****
  • Posts: 3096
Getting Caller function or Procedure.
« on: September 03, 2017, 04:00:21 pm »
When debugging you can use the stack track determine who called the current function..

I know how this is done in the background via ASM but is there a ready made function in
Fpc that returns the pointer to the procedure or function that it will return back to?

 Like for example, GetReturnCallAddress or something like that ? I would like to identify
what procedure or function called the current block, just like stack track does but only part of
your app..

 Like I said, I can do this with ASM inline but I would like to do this at a more human level, one
that is cross platform friendly.
The only true wisdom is knowing you know nothing

jamie

  • Hero Member
  • *****
  • Posts: 3096
Re: Getting Caller function or Procedure.
« Reply #1 on: September 03, 2017, 04:41:15 pm »
I think I found it.
Get_caller_Addr

and a couple of others that go with it.
The only true wisdom is knowing you know nothing

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 787
    • Lebeau Software
Re: Getting Caller function or Procedure.
« Reply #2 on: September 06, 2017, 12:06:27 am »
If you figure out how to use it, let me know.  Indy has an IndyRaiseOuterException() function that just throws an exception at the caller's return address (ie, "raise E at <address>") on systems where SysUtils.Exception.RaiseOuterException() is not available (like FreePascal).  On systems where Delphi's System.ReturnAddress intrinsic is not available (ie, "raise E at ReturnAddress"), I resort to inline assembly to get the return address manually.

It would be nice if FreePascal had something like Delphi's ReturnAddress intrinsic.  But it doesn't, and I wasn't sure what capabilities FreePascal actually had, so IndyRaiseOuterException() only uses "raise E" and not "raise E at <address>".

I just found this FreePascal documentation, The raise statement, which has this code example:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}  
  2. uses sysutils;  
  3.  
  4. procedure error(Const msg : string);  
  5.  
  6. begin  
  7.   raise exception.create(Msg) at  
  8.     get_caller_addr(get_frame),  
  9.     get_caller_frame(get_frame);  
  10. end;  
  11.  
  12. procedure test2;  
  13.  
  14. begin  
  15.   error(’Error’);  
  16. end;  
  17.  
  18. begin  
  19.   test2;  
  20. end.

Does get_caller_addr() work in all modes, or only in objfpc mode?  Indy runs in Delphi mode.  Does get_caller_addr(get_frame) work even if stack frames are disabled?  And why is get_caller_frame() being passed as an argument to "raise ... at"?
« Last Edit: September 06, 2017, 12:11:08 am by Remy Lebeau »
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

 

TinyPortal © 2005-2018