How to know the know calling function name by C programme

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mcarthybn
    New Member
    • Jun 2009
    • 7

    How to know the know calling function name by C programme

    hi ,
    I am working on huge C programming project.I am doin debugging only by printf
    measn i dont have any dubugger .So it is very difficult know who is actually calling a function and i am stuck in a problem that , i have seen that one fucntion is get called by from some 160 postions. and i need to solve some problem and it is very probmatic to get print from 160 postions.So ,is there any way to get to know who is calling that function in runtime ? Is there any small programme or trick will be there , get to know who is calling that function in runtime.so i can print that function name inside that called function or any other way and my work will be easy .

    Please help me on this.
    I am waiting for your reply
    Thanks
    mcarthy
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Well here is a hack that might help you, it wont identify the calling function but will identify the calling line of code.

    Lets assume that you function is defined like so

    Code:
    int aFunction(int param)
    {
        ...
    }
    Declared in a header like so

    Code:
    extern int aFunction(int param);
    and called like so

    Code:
    int result;
    int param;
    
    // initialise param
    
    ...
    
    result = aFunction(param);
    
    ...
    
    // use result
    You make use of the __LINE__ and __FILE__ predefine macros in C that resolve to the current line number and current file name. You can use these along with the C/C++ preprocessor to crowbar some debuging into your code by making the following modifications

    Cahnge the function definition to
    Code:
    int aFunctionWithDebug(int param, const char *file, int line)
    {
        printf("%s(%d): Called aFunction\n", file, line);
        ...
    }
    Change the declaration in the header file to

    Code:
    extern int aFunctionWithDebug(int param);
    #define aFunction(param)       aFunctionWithDebug(param)
    and don't change the call to the function at all.

    Code:
    int result;
    int param;
    
    // initialise param
    
    ...
    
    result = aFunction(param);
    
    ...
    
    // use result
    You will need to recompile your entire source (which sounds like it could take a while) and if you get the macro or any calls to the function wrong you will get not entirely intuitive compiler diagnostics but the printf would output something like

    /home/user/source/file.c(45): called a function

    which would allow you to locate the function call.

    If you are using a C99 compiler (gcc for instance) then you could use the __FUNCTION__ in a similar manor. This actually resolves to the current function name. gcc has an extension of this __PRETTY_FUNCTI ON__ which outputs the function declaration.

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      If you can find out the calling conventions of your particular compiler then you can hack a very nonportable mechanism for printing the call tree [who called who to get to where you are].

      For instance, perhaps your compiler invariably creates a stack frame by loading one particular register with the value of the stack pointer upon entry to each function. Unwrapping the stack frames is the same as unwrapping the function calls.

      This technique only gives you the address from which each function was called; you will have to consult a link map to translate that to function name.

      Be sure your trace unwrapper will terminate so you don't loop forever.

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        I would recommend installing a logfile.

        By this I mean a circular text file of, say 256 fixed-length records. That is a flat file. The first record contains a counter indicating the record to write to next. After writing, the counter in the first record is incremented. When it gets to 255, it is reset to 1 (record 0 has the counter, record 1 is the first log entry).

        This way the file never has more than 256 records and can run indefinitely without requiring maintenance of any sort.

        In addition, I would add a system setting that the logfile fuinction can test to determine whether logging is turned on or not. When logging is off, the logfile function is a null function. Usually, I have a second setting for the logfile pathname.

        Implement this as you would fprintf:

        Code:
        int LogFile(char* arg, ...);
        Then when you call a function you could:

        Code:
        void MyFunc(char* arg)
        {
           Logfile("%s%d", "MyFunc calling YourFunc with a", 10);
           YourFunc(10);
        
        }
        The Logfile function now becomes part of your production program. In crash cases the logfile is cool since after the program aborts, the last 256 log entries are still in the logfile and are the input to the crash autopsy.

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          You can add a severity argument to the Logfile function; for example, severity could be an enumerated type with values Failure, Warning, and Memo. Then provide another function to set the minimum severity that gets written into the log.

          Comment

          • donbock
            Recognized Expert Top Contributor
            • Mar 2008
            • 2427

            #6
            C99 supports preprocessor macros with a variable number of parameters; however C89 does not. If your compiler supports this feature then you could do something like this:
            Code:
            int LogFileFunc(const char *file, int line, const char *fmt, ...);
            
            #define LogFile(fmt, ...) \
                LogFileFunc(__FILE__, __LINE__, fmt, __VA_ARGS__)
            The macro automates inclusion of the file name and line number in the LogFileFunc call. You could do this without a macro if you took the time to always type "__FILE__,__LIN E__," as the first arguments to LogFileFunc.

            I know C++ users don't like to use preprocessor macros. Is there some other clever way to do this in C++?

            Comment

            • mcarthybn
              New Member
              • Jun 2009
              • 7

              #7
              hi ,
              My question is to know the caller function name because if i put __FILE__ in my function , obviously it will not help to know who is caller of my function.
              According to donbock how to print the stack tree or capture the stack pointer or link register , so it will help in crash time also heavily..

              Regarding log file also , i have to put everywhere where a function are get called., so it will not help me to solve bug/crash quick way.

              How other editor capturing the stack tree, so cant we make such kind of way.

              Any help .please
              Mcarthy

              Comment

              • JosAH
                Recognized Expert MVP
                • Mar 2007
                • 11453

                #8
                Originally posted by mcarthybn
                hi ,
                My question is to know the caller function name because if i put __FILE__ in my function , obviously it will not help to know who is caller of my function.
                If you have one function per file ...

                kind regards,

                Jos

                Comment

                • donbock
                  Recognized Expert Top Contributor
                  • Mar 2008
                  • 2427

                  #9
                  Originally posted by JosAH
                  Originally posted by mcarthybn
                  My question is to know the caller function name because if i put __FILE__ in my function , obviously it will not help to know who is caller of my function.
                  If you have one function per file ...
                  That won't tell you who the caller of your function was. The only way to do that is to unwind the return addresses from the stack. The OP needs to research the details of how his compiler implements function calls.

                  Comment

                  • weaknessforcats
                    Recognized Expert Expert
                    • Mar 2007
                    • 9214

                    #10
                    Unwinding the stack will not produce the function names. Everything is in binary.

                    If you need the actual function name, then you have to compile it into the program.

                    I'm sorry if it takes code to implement a log file to capture calling function names but that's the way it is. It is no more difficult than implementing reference counting in C.

                    I would write the logfile function and get it working. Then I would install the logfile function calls in what I deem to be the most likely problem areas. Most likely at the end of the day, you won't need to log every last function call.

                    My logfile entries are more general in nature and reflect the type of processing that's going on.

                    Comment

                    • ratnesh123
                      New Member
                      • Jan 2010
                      • 1

                      #11
                      StackWalk64

                      how about using StackWalk64 API
                      have a look at http://msdn.microsoft. com/en-us/library/ms680650%28VS.8 5%29.aspx
                      I have attached a sample project
                      Attached Files

                      Comment

                      • Sridhar V

                        #12
                        You can use this if you use gcc.


                        I like donbock's solution a macro instead of the actual function which gives line numbers too. If you dont want that , walk through the stack using the backtrace function. And resolve symbols.

                        Comment

                        • fatalfeel
                          New Member
                          • Jul 2008
                          • 1

                          #13
                          caller name full source build for x86_64 and aarch64 in linux
                          1. down binutils and build ~~~binutils 2.25.1 x86_64 & aarch64 both build pass other version may be not~~~ download:  https://ftp.gnu.org/gn...

                          Comment

                          Working...