Question : A generic function to retrieve the call parameters of a function 
Author Message
 Question : A generic function to retrieve the call parameters of a function

Hi !

I am trying to find a nice way to retrieve the parameter list of functions
in a generic way. The target is to do remote debugging for a m68k board.

DESCRIPTION of our currently used code :
------------------------------------------

The system we use currently works, but it is not elegant:
We insert at the start of each function a few lines of code.
(such as :
#if dbglobal
     xdbgfp = (char *)(&c);
     dbafns(0x0227);
#endif
)

Here's an example :
Suppose we want to monitor calls to the following functions :

tfunc01(char c, short s, long l, float f)
{
/*......
local variables or the function
......*/

 #if dbglobal
     xdbgfp = (char *)(&c);
     dbafns(0x0227);
 #endif

/*......
code of the function
......*/

Quote:
}

void tfunc02(char *c, short *s, long *l, float *f)
{
 #if dbglobal
     xdbgfp = (char *)(&c);
     dbafns(0x0228);
 #endif

Quote:
}

The fuction dbafns( FUNCTION_ID) is called with a number unique for that
function.
We process the source code and map files to identify the types of the
parameters when dbafns is
called with FUNCTION_ID.
We then read the the values starting at location xdbgfp, using the type data
extracted from the source
code. The function call parameter list is sent via serial port to the remote
debugging software.

Sample output for dbafns():

tfunc01(char c, short s, long l, float f)
  Parameters = 35,30600,1122867,13.789540

tfunc02(char *c, short *s, long *l, float *f)
  Parameters = P1(0x004027FB),P2(0x004027EE),P3(0x004027F0),P4(0x004027F4)
  ..P1(0x004027FB), = 35,0
  ..P2(0x004027EE), = 30600
  ..P3(0x004027F0), = 1122867
  ..P4(0x004027F4), = 13.789540

QUESTION :
-----------
A problem is that we need to add the xdbgfp = (char *)(&c); line every time.

We would like to use the following code only at each funtion:
#if dbglobal
     xdbgfp = PARPOINTER;
     dbafns(0x0227);
#endif

With PARPOINTER = a fixed expression to retrieve the start address of the
parameter list of a function
(not dependent of the actual paremeter names) ?

Even better would be a way to do this by only inserting
#if dbglobal
     dbafns(0x0227);
#endif
the PARPOINTER should then be calculated in dbafns().

OR even use only
#if dbglobal
     dbafns();
#endif
(then we also need retrieve the function pointer in dbafns())

Does anyone have a clever idea to solve/improve this ? Can this be solved in
pure C code?

Thanks !

Serge Defever
--



Sun, 18 May 2003 03:00:00 GMT  
 Question : A generic function to retrieve the call parameters of a function

Quote:

> I am trying to find a nice way to retrieve the parameter list of functions
> in a generic way. The target is to do remote debugging for a m68k board.

The usual way would be by instrumenting the code, as you're doing it,
but doing it at least partly automatically. I.e. instead of
hand-written code to be added to each function, make use of debugging
information provided by your compiler and machine-generate the
necessary stuff either on source-code or on object file level.

Quote:
> QUESTION :
> -----------
> A problem is that we need to add the xdbgfp = (char *)(&c); line every time.
[...]
> Does anyone have a clever idea to solve/improve this ?

It's not really particularly clever, nor does it have much to do with
C as a programming language, i.e. you might be better off asking for
details elsewhere: dbafns() would have to become a macro that contains
some inline assembly code to be executed right after entering the
function but after the function entry code, essentially. It would look
at the registers and stack contents and extract the function's address
and the local variables from it.

This is all extremely platform-dependant. If you have access to such
information, you may want to look at the way your compiler uses to
instrument functions for profiling, itself.

Quote:
> Can this be solved in pure C code?

No.
--

Even if all the snow were burnt, ashes would remain.
--



Mon, 19 May 2003 14:09:25 GMT  
 Question : A generic function to retrieve the call parameters of a function
Quote:

> Hi !

> I am trying to find a nice way to retrieve the parameter list of functions
> in a generic way. The target is to do remote debugging for a m68k board.

> DESCRIPTION of our currently used code :
> ------------------------------------------

> The system we use currently works, but it is not elegant:
> We insert at the start of each function a few lines of code.
> (such as :
> #if dbglobal
>      xdbgfp = (char *)(&c);
>      dbafns(0x0227);
> #endif
> )

> Here's an example :
> Suppose we want to monitor calls to the following functions :

> tfunc01(char c, short s, long l, float f)
> {
> /*......
> local variables or the function
> ......*/

>  #if dbglobal
>      xdbgfp = (char *)(&c);
>      dbafns(0x0227);
>  #endif

> /*......
> code of the function
> ......*/
> }

> void tfunc02(char *c, short *s, long *l, float *f)
> {
>  #if dbglobal
>      xdbgfp = (char *)(&c);
>      dbafns(0x0228);
>  #endif
> }

> The fuction dbafns( FUNCTION_ID) is called with a number unique for that
> function.
> We process the source code and map files to identify the types of the
> parameters when dbafns is
> called with FUNCTION_ID.
> We then read the the values starting at location xdbgfp, using the type data
> extracted from the source
> code. The function call parameter list is sent via serial port to the remote
> debugging software.

> Sample output for dbafns():

> tfunc01(char c, short s, long l, float f)
>   Parameters = 35,30600,1122867,13.789540

> tfunc02(char *c, short *s, long *l, float *f)
>   Parameters = P1(0x004027FB),P2(0x004027EE),P3(0x004027F0),P4(0x004027F4)
>   ..P1(0x004027FB), = 35,0
>   ..P2(0x004027EE), = 30600
>   ..P3(0x004027F0), = 1122867
>   ..P4(0x004027F4), = 13.789540

> QUESTION :
> -----------
> A problem is that we need to add the xdbgfp = (char *)(&c); line every time.

> We would like to use the following code only at each funtion:
> #if dbglobal
>      xdbgfp = PARPOINTER;
>      dbafns(0x0227);
> #endif

> With PARPOINTER = a fixed expression to retrieve the start address of the
> parameter list of a function
> (not dependent of the actual paremeter names) ?

> Even better would be a way to do this by only inserting
> #if dbglobal
>      dbafns(0x0227);
> #endif
> the PARPOINTER should then be calculated in dbafns().

> OR even use only
> #if dbglobal
>      dbafns();
> #endif
> (then we also need retrieve the function pointer in dbafns())

> Does anyone have a clever idea to solve/improve this ? Can this be solved in
> pure C code?

> Thanks !

> Serge Defever
> --


gdb is able to extract all the information necessary from an executable
compiled with debug info. What about extracting the information from the executable
and use the code from gdb? This code is C and works for many platforms.
--

Patzschke + Rasp Software AG                        http://www.prs.de
Bierstadter Stra?e 7                          Fax: +49-(0)611-1731-31
D-65189 Wiesbaden       Phone: +49-(0)611-1731-611/+49-(0)173-9405050
--



Mon, 19 May 2003 14:10:11 GMT  
 Question : A generic function to retrieve the call parameters of a function
You can do some of this in pure C code. For example, if you
define (in some ".h" file somewhere)

  #if dbglobal
    #define DBANFS(x) do{\
      xdbgfp = (char *)(&c);\
      dbafns(x);\
      }while(0)
  #else
    #define DBANFS(x)
  #endif

*and* (silly requirement) made sure every function being debugged had
"c" (of any type) as the very first parameter (i.e., added a "dummy"
parameter "c" to parameter-less functions), then you could rewrite your
functions like this:

tfunc01(char c, short s, long l, float f)
{
  /*......
  local variables or the function
  ......*/

     DBANFS(0x0227);

  /*......
  code of the function
  ......*/

Quote:
}

void tfunc02(char *c, short *s, long *l, float *f)
{
     DBANFS(0x0228);

Quote:
}

Prettier, but it doesn't address the difficult problems.
If each function merely needs a unique number (rather than sequential
numbers),
you might try experimenting with something like

void tfunc02(char *c, short *s, long *l, float *f)
{
     DBANFS(tfunc02);

Quote:
}

which returns the (unique) address of the function ...

I think my compiler can calculate the equivalent of PARPOINTER with
something like this (untested, off the top of my head, probably won't
work):

    #define DBANFS(x) do{\
      asm{ MOV.l r7 xdbgfp; };\
      dbafns(x);\
      }while(0)

where r7 is the "frame pointer". This requires me to set the "enable
frame pointer" compiler option, and my compiler refuses to do any
optimization in any functions with asm{} statements, so this might be
too much hassle.

Have you looked at the GNU de{*filter*} gdb
  http://www.*-*-*.com/
?

I think it does something similar to what you're trying to do, and since
it's open-source ...


Quote:
> I am trying to find a nice way to retrieve the parameter list of
functions
> in a generic way. The target is to do remote debugging for a m68k
board.

> DESCRIPTION of our currently used code :
> ------------------------------------------

> The system we use currently works, but it is not elegant:
> We insert at the start of each function a few lines of code.
...
> Here's an example :
> Suppose we want to monitor calls to the following functions :

> tfunc01(char c, short s, long l, float f)
> {
> /*......
> local variables or the function
> ......*/

>  #if dbglobal
>      xdbgfp = (char *)(&c);
>      dbafns(0x0227);
>  #endif

> /*......
> code of the function
> ......*/
> }

> void tfunc02(char *c, short *s, long *l, float *f)
> {
>  #if dbglobal
>      xdbgfp = (char *)(&c);
>      dbafns(0x0228);
>  #endif
> }

> The fuction dbafns( FUNCTION_ID) is called with a number unique for
that
> function.
> We process the source code and map files to identify the types of the
> parameters when dbafns is
> called with FUNCTION_ID.
> We then read the the values starting at location xdbgfp, using the
type data
> extracted from the source
> code. The function call parameter list is sent via serial port to the
remote
> debugging software.

> Sample output for dbafns():

> tfunc01(char c, short s, long l, float f)
>   Parameters = 35,30600,1122867,13.789540

> tfunc02(char *c, short *s, long *l, float *f)
>   Parameters =

P1(0x004027FB),P2(0x004027EE),P3(0x004027F0),P4(0x004027F4)

- Show quoted text -

Quote:
>   ..P1(0x004027FB), = 35,0
>   ..P2(0x004027EE), = 30600
>   ..P3(0x004027F0), = 1122867
>   ..P4(0x004027F4), = 13.789540

> QUESTION :
> -----------
> A problem is that we need to add the xdbgfp = (char *)(&c); line every
time.

> We would like to use the following code only at each funtion:
> #if dbglobal
>      xdbgfp = PARPOINTER;
>      dbafns(0x0227);
> #endif

> With PARPOINTER = a fixed expression to retrieve the start address of
the
> parameter list of a function
> (not dependent of the actual paremeter names) ?

> Even better would be a way to do this by only inserting
> #if dbglobal
>      dbafns(0x0227);
> #endif
> the PARPOINTER should then be calculated in dbafns().

> OR even use only
> #if dbglobal
>      dbafns();
> #endif
> (then we also need retrieve the function pointer in dbafns())

> Does anyone have a clever idea to solve/improve this ? Can this be
solved in
> pure C code?

> Thanks !

> Serge Defever
> --


--



Mon, 19 May 2003 03:00:00 GMT  
 Question : A generic function to retrieve the call parameters of a function
Hans-Bernhard,
thanks for your response.
We indeed actually use inline assembler inside dbafns() to travel the stack.
We made a utility that extracts information from the compiler's map files,
and inserts corresponding numbering in the source code as the parameter for
dbafns().
This all is indeed very platform and compiler specific. We hoped to find a
clean platform- and compiler independent way to do this, by posing the
question to the comp.lang.c  group. But (as we already expected)  I guess
that's impossible.

We will modify our utility to automatically insert the xdbgfp = ...; line in
the source code. It's not an elegant solution, but it can work.

Regards & Thanks,
Serge


Quote:

> > I am trying to find a nice way to retrieve the parameter list of
functions
> > in a generic way. The target is to do remote debugging for a m68k board.

> The usual way would be by instrumenting the code, as you're doing it,
> but doing it at least partly automatically. I.e. instead of
> hand-written code to be added to each function, make use of debugging
> information provided by your compiler and machine-generate the
> necessary stuff either on source-code or on object file level.

> > QUESTION :
> > -----------
> > A problem is that we need to add the xdbgfp = (char *)(&c); line every
time.
> [...]
> > Does anyone have a clever idea to solve/improve this ?

> It's not really particularly clever, nor does it have much to do with
> C as a programming language, i.e. you might be better off asking for
> details elsewhere: dbafns() would have to become a macro that contains
> some inline assembly code to be executed right after entering the
> function but after the function entry code, essentially. It would look
> at the registers and stack contents and extract the function's address
> and the local variables from it.

> This is all extremely platform-dependant. If you have access to such
> information, you may want to look at the way your compiler uses to
> instrument functions for profiling, itself.

> > Can this be solved in pure C code?

> No.
> --

> Even if all the snow were burnt, ashes would remain.
> --


--



Mon, 19 May 2003 03:00:00 GMT  
 Question : A generic function to retrieve the call parameters of a function
Wolfgang,
thanks for your response.

We made a utility that extracts information from the compiler's map files,
and inserts corresponding numbering in the source code as the parameter for
dbafns().Unfortunately, this all is indeed very platform and compiler
specific. (We use the Green Hills compiler)

We will modify our utility to automatically insert the xdbgfp = ...; line in
the source code. It's not an elegant solution, but it can work.

Regards & Thanks,
Serge

We will modify our utility to automatically insert the xdbgfp = ...; line in
the source code. It's not an elegant solution, but it can work.

Regards & Thanks,
Serge



Quote:

> > Hi !

> > I am trying to find a nice way to retrieve the parameter list of
functions
> > in a generic way. The target is to do remote debugging for a m68k board.

> > DESCRIPTION of our currently used code :
> > ------------------------------------------

> > The system we use currently works, but it is not elegant:
> > We insert at the start of each function a few lines of code.
> > (such as :
> > #if dbglobal
> >      xdbgfp = (char *)(&c);
> >      dbafns(0x0227);
> > #endif
> > )

> > Here's an example :
> > Suppose we want to monitor calls to the following functions :

> > tfunc01(char c, short s, long l, float f)
> > {
> > /*......
> > local variables or the function
> > ......*/

> >  #if dbglobal
> >      xdbgfp = (char *)(&c);
> >      dbafns(0x0227);
> >  #endif

> > /*......
> > code of the function
> > ......*/
> > }

> > void tfunc02(char *c, short *s, long *l, float *f)
> > {
> >  #if dbglobal
> >      xdbgfp = (char *)(&c);
> >      dbafns(0x0228);
> >  #endif
> > }

> > The fuction dbafns( FUNCTION_ID) is called with a number unique for that
> > function.
> > We process the source code and map files to identify the types of the
> > parameters when dbafns is
> > called with FUNCTION_ID.
> > We then read the the values starting at location xdbgfp, using the type
data
> > extracted from the source
> > code. The function call parameter list is sent via serial port to the
remote
> > debugging software.

> > Sample output for dbafns():

> > tfunc01(char c, short s, long l, float f)
> >   Parameters = 35,30600,1122867,13.789540

> > tfunc02(char *c, short *s, long *l, float *f)
> >   Parameters =

P1(0x004027FB),P2(0x004027EE),P3(0x004027F0),P4(0x004027F4)

- Show quoted text -

Quote:
> >   ..P1(0x004027FB), = 35,0
> >   ..P2(0x004027EE), = 30600
> >   ..P3(0x004027F0), = 1122867
> >   ..P4(0x004027F4), = 13.789540

> > QUESTION :
> > -----------
> > A problem is that we need to add the xdbgfp = (char *)(&c); line every
time.

> > We would like to use the following code only at each funtion:
> > #if dbglobal
> >      xdbgfp = PARPOINTER;
> >      dbafns(0x0227);
> > #endif

> > With PARPOINTER = a fixed expression to retrieve the start address of
the
> > parameter list of a function
> > (not dependent of the actual paremeter names) ?

> > Even better would be a way to do this by only inserting
> > #if dbglobal
> >      dbafns(0x0227);
> > #endif
> > the PARPOINTER should then be calculated in dbafns().

> > OR even use only
> > #if dbglobal
> >      dbafns();
> > #endif
> > (then we also need retrieve the function pointer in dbafns())

> > Does anyone have a clever idea to solve/improve this ? Can this be
solved in
> > pure C code?

> > Thanks !

> > Serge Defever
> > --

> gdb is able to extract all the information necessary from an executable
> compiled with debug info. What about extracting the information from the
executable
> and use the code from gdb? This code is C and works for many platforms.
> --

> Patzschke + Rasp Software AG                        http://www.prs.de
> Bierstadter Stra?e 7                          Fax: +49-(0)611-1731-31
> D-65189 Wiesbaden       Phone: +49-(0)611-1731-611/+49-(0)173-9405050
> --


--



Mon, 19 May 2003 03:00:00 GMT  
 Question : A generic function to retrieve the call parameters of a function
Dear Serge Defever,

I just discovered one way of retrieving the parameter list of functions
in a generic way on many platforms, but only using the GNU C compiler.
(GCC can be set up to cross-compile to 68000 assembly, but if what you
have now works, it may not be worthwhile to convert to GCC).

(Is there a more authoritative URI for the EGCS manual ?)
http://www.math.umn.edu/systems_guide/egcs-1.1.2/gcc_4.html#SEC63
says:

<blockquote>
---------------------------
Constructing Function Calls

Using the built-in functions described below, you can record the
arguments a function received, and call another function with the same
arguments,
without knowing the number or types of the arguments.

You can also record the return value of that function call, and later
return that value, without knowing what data type the function tried to
return (as
long as your caller expects that data type).

__builtin_apply_args ()
       This built-in function returns a pointer of type void * to data
describing how to perform a call with the same arguments as were passed
to
       the current function. The function saves the arg pointer
register, structure value address, and all registers that might be used
to pass
       arguments to a function into a block of memory allocated on the
stack. Then it returns the address of that block.

__builtin_apply (function, arguments, size)
       This built-in function invokes function (type void (*)()) with a
copy of the parameters described by arguments (type void *) and size
       (type int). The value of arguments should be the value returned
by __builtin_apply_args. The argument size specifies the size of the
stack
       argument data, in bytes. This function returns a pointer of type
void * to data describing how to return whatever value was returned by
       function. The data is saved in a block of memory allocated on the
stack. It is not always simple to compute the proper value for size. The
       value is used by __builtin_apply to compute the amount of data
that should be pushed on the stack and copied from the incoming argument
       area.

__builtin_return (result)
       This built-in function returns the value described by result from
the containing function. You should specify, for result, a value
returned by
       __builtin_apply.

</blockquote>

...

Quote:
> Unfortunately, this all is indeed very platform and compiler
> specific. (We use the Green Hills compiler)
...

...
> > > I am trying to find a nice way to retrieve the parameter list of
> functions
> > > in a generic way. The target is to do remote debugging for a m68k
board.

> > > DESCRIPTION of our currently used code :
> > > ------------------------------------------

> > > The system we use currently works, but it is not elegant:
> > > We insert at the start of each function a few lines of code.
> > > (such as :
> > > #if dbglobal
> > >      xdbgfp = (char *)(&c);
> > >      dbafns(0x0227);
> > > #endif
> > > )
...
> > > Does anyone have a clever idea to solve/improve this ? Can this be
> solved in
> > > pure C code?

...
--



Tue, 17 Jun 2003 02:36:10 GMT  
 Question : A generic function to retrieve the call parameters of a function
"It is not always simple to compute the proper value for size. The value is
used by __builtin_apply to compute the amount of data that should be pushed
on the stack and copied from the incoming argument area. "

1. How do you compute the size?
2. If I have two identical machines, can I pass these parameters via
    the network, and invoke the method on the second machine?
3. How is the first function being invoked ? As I understand its invokation
    should be identical to the destenation function invokation, having the
    same arguments.  But, the whole mechanism looks like it has been
    designed for a generic case, so the first function should not need to
   declare the same argument list, since it just pass it to an other
function.
   So, How is it being invoked, and declared?
--



Wed, 02 Jul 2003 10:16:08 GMT  
 Question : A generic function to retrieve the call parameters of a function
Dear "G",

I've never actually used these functions, but that never stopped me from
speculating before ... Someone please point me at good documentation.


Quote:
>> "It is not always simple to compute the proper value for size. The
value is
>> used by __builtin_apply to compute the amount of data that should be
pushed
>> on the stack and copied from the incoming argument area. "

> 1. How do you compute the size?

Good question. I believe that the size needed varies from one compiler
to the next. It appears that if you tell __builtin_apply() a
"conservative" "worst-case" size that's larger than the amount of stack
actually used by parameters to foo(), everything still works fine.

Quote:
> 2. If I have two identical machines, can I pass these parameters via
>     the network, and invoke the method on the second machine?

I don't see why not. (Assuming identical machines, identical compilers,
appropriate routines to memcpy() the appropriate chunk of the parameter
stack, etc.).

Quote:
> 3. How is the first function being invoked ? As I understand its
invokation
>     should be identical to the destenation function invokation, having the
>     same arguments.  But, the whole mechanism looks like it has been
>     designed for a generic case, so the first function should not need to
>    declare the same argument list, since it just pass it to an other
> function.
>    So, How is it being invoked, and declared?

I wish I knew myself. I have the same question about the return value.

It looks like these __builtin things were designed to be used in a
function with ellipses parameters
( see
  http://www.eskimo.com/~scs/C-faq/q15.4.html
).

float test( ... ) /* literally 3 dots here */
{
   __builtin_return(
        __builtin_apply(
            (void (*)()) function_under_test,
            __builtin_apply_args(),
            0) );

Quote:
}

Here's a complete test program:
  http://gcc.gnu.org/ml/gcc-bugs/1999-09n/msg00242.html
--



Sun, 06 Jul 2003 14:30:36 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Question : A generic function to retrieve the call parameters of a function

2. Call a function in a function with name of a function as parameter

3. Calling DLL functions without known function name, parameter-list until run-time

4. Function Parameters Change when function called?!

5. Function Parameters Change when function called?!

6. function parameters and return values aren't changed by function call

7. Function Parameters Change when function called?!

8. Retrieve storedproc parameters + Factory Pattern generic data access

9. Calling generic object functions

10. Pointers to functions for generic functions

11. Passing and retrieving a buffer calling a c++ function

12. Condition breakpoints and function calls and function calls in Immediate window

 

 
Powered by phpBB® Forum Software