Gets the address of the calling function

Just starting out? Need help? Post your questions and find answers here.
zgneng
User
User
Posts: 29
Joined: Sun Jun 28, 2015 9:04 am

Gets the address of the calling function

Post by zgneng »

Code: Select all


Global p.l

Procedure pp1()
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me

!mov [v_p],ebp 

Debug  Hex(p+4) ;ERRO


EndProcedure


Procedure pp2()
  
  
  pp1()
  
  
EndProcedure


Debug "address:" + Hex(@pp2())
                                   
pp2()


@pp2() unknown


Get the call pp2() function address


Gets the address of the calling function

or (PP2) the caller.


Can not use @
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Re: Gets the address of the calling function

Post by srod »

Not a chance! :) You could use ASM to get the return address, which will of course reside within the calling function. You could probably use this mind with functions marked as 'runtime' to then identify the calling function, but this requires the runtime lib.

Easiest thing to do is simply pass the address of the calling function as a parameter.

Code: Select all

Global p.l

Procedure pp1(addressOfCallingFunction)
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me
  
  ; I want To get the one who calls me

Debug addressOfCallingFunction

EndProcedure


Procedure pp2()
  pp1(@pp2())
EndProcedure
I may look like a mule, but I'm not a complete ass.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Gets the address of the calling function

Post by Lunasole »

You can use ASM to push caller's adress to one of registers before making call, and then get it from called function. But this makes no sense as it is more clear to use something like that

Code: Select all

EnableExplicit

Global *A_freedom_to_go_home

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Procedure SomeProc ()
	CallFunctionFast(*A_freedom_to_go_home, #False)
EndProcedure


Procedure Caller1 (jmp)
	*A_freedom_to_go_home = @Caller1()
	Debug "Caller1: " + Str(jmp)
	If jmp
		SomeProc()
	EndIf
EndProcedure

Procedure Caller2 (jmp)
	*A_freedom_to_go_home = @Caller2()
	Debug "Caller2: " + Str(jmp)
	If jmp
		SomeProc()
	EndIf
EndProcedure


;;;;;;;;;;;;;;;;;;;;;;;;

Caller1(#True)
Caller2(#True)
This can also be made as a preprocessing tool for IDE, but it doesn't make it less ugly and poor. Even more, causes problems when you try to share some your preprocessed code.
That all is of course just a shitty workaround, and this makes me angry as I remember when I needed such thing. I don't understand why not just add support of this little and useful stuff at compiler level, as it is added to any adequate compiler of language where low-level stuff/callbacks used often. GCC has it, for example, and I guess MSVC too.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
User avatar
Olliv
Enthusiast
Enthusiast
Posts: 542
Joined: Tue Sep 22, 2009 10:41 pm

Re: Gets the address of the calling function

Post by Olliv »

zgneng wrote:Can not use @
加上頭聲明計劃
Just add:

Code: Select all

Declare pp2()
...on the top of your code.
zgneng
User
User
Posts: 29
Joined: Sun Jun 28, 2015 9:04 am

Re: Gets the address of the calling function

Post by zgneng »

Lunasole wrote:You can use ASM to push caller's adress to one of registers before making call, and then get it from called function. But this makes no sense as it is more clear to use something like that

Code: Select all

EnableExplicit

Global *A_freedom_to_go_home

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Procedure SomeProc ()
	CallFunctionFast(*A_freedom_to_go_home, #False)
EndProcedure


Procedure Caller1 (jmp)
	*A_freedom_to_go_home = @Caller1()
	Debug "Caller1: " + Str(jmp)
	If jmp
		SomeProc()
	EndIf
EndProcedure

Procedure Caller2 (jmp)
	*A_freedom_to_go_home = @Caller2()
	Debug "Caller2: " + Str(jmp)
	If jmp
		SomeProc()
	EndIf
EndProcedure


;;;;;;;;;;;;;;;;;;;;;;;;

Caller1(#True)
Caller2(#True)
This can also be made as a preprocessing tool for IDE, but it doesn't make it less ugly and poor. Even more, causes problems when you try to share some your preprocessed code.
That all is of course just a shitty workaround, and this makes me angry as I remember when I needed such thing. I don't understand why not just add support of this little and useful stuff at compiler level, as it is added to any adequate compiler of language where low-level stuff/callbacks used often. GCC has it, for example, and I guess MSVC too.

PP2 () is unknown
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Gets the address of the calling function

Post by Lunasole »

zgneng wrote: PP2 () is unknown
But you making it known when doing things like at that code, so this is possible (and ugly) solution if you have full control over all sources.

Surely it will not work if for example some external lib does callback to your function. Then there seems to be no chances, unless this thing is not implemented in PB compiler. But i didn't performed any detailed disasm for such cases using external disassembler (instead of built-in, which might not give the full picture), maybe someone knows better, I can only say that all what PB itself provides for such backtracking is whole nothing and this is ridiculous.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
Post Reply