![]() |
Function invocation location
I was wondering if it would be possible to find out, from within a
function, the file and line number where that particular function call was invoked, bearing in mind that the function can potentially be invoked from many different files. I guess that what I am looking for is something similar to the __FILE__ and __LINE__ symbols, but one level up in the function call stack. |
Re: Function invocation location
1.41421@gmail.com writes:
> I was wondering if it would be possible to find out, from within a > function, the file and line number where that particular function call > was invoked, bearing in mind that the function can potentially be > invoked from many different files. I guess that what I am looking for > is something similar to the __FILE__ and __LINE__ symbols, but one > level up in the function call stack. No, there's no good portable way to do that. You could probably do something involving passing extra arguments to your functions, but it wouldn't be pretty. A source level debugger should be able to show this information interactively. What are you trying to accomplish? -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. |
Re: Function invocation location
I use macros to do it
#include <stdio.h> #define perform_action(a) _perform_action((a),__FILE__,__LINE__) void _perform_action(int actCd, const char * file, int lineno); void _perform_action(int actCd, const char * file, int lineno) { printf("Called perform_action from %s:%d\n", file, lineno); } int main(void) { perform_action(4); return 0; } |
Re: Function invocation location
Keith Thompson wrote:
> 1.41421@gmail.com writes: > > I was wondering if it would be possible to find out, from within a > > function, the file and line number where that particular function call > > was invoked, bearing in mind that the function can potentially be > > invoked from many different files. I guess that what I am looking for > > is something similar to the __FILE__ and __LINE__ symbols, but one > > level up in the function call stack. > > No, there's no good portable way to do that. > > You could probably do something involving passing extra arguments to > your functions, but it wouldn't be pretty. > > A source level debugger should be able to show this information > interactively. > > What are you trying to accomplish? Pretty much what I said: To find out who is invoking a certain function, and at what point. I am using an embedded environment, and a source level debugger does disturb things so that what I am trying to see is not there anymore. The only way I could think of to do it is by means of the info above, and well-placed printf (the output of which goes to a console accessible through a serial port). |
Re: Function invocation location
You can also (sometimes) get stack trace information on linux with the
functions: backtrace and backtrace_symbols. I don't remember what information you could get from the functions (if it was file, line, or function/symbol name), but I think you could get symbol names for functions that weren't static. |
Re: Function invocation location
castillo.bryan@gmail.com writes:
> I use macros to do it You use macros to do what? Please read <http://cfaj.freeshell.org/google/>. Google's posting interface is badly broken, but it can be used correctly with just a little extra effort. > #include <stdio.h> > > #define perform_action(a) _perform_action((a),__FILE__,__LINE__) > void _perform_action(int actCd, const char * file, int lineno); Avoid identifiers with leading underscores. Many of them are reserved for use by the implementation. Rather than memorizing or looking up the rules for which ones are reserved in which contexts, it's best to just avoid them altogether (unless you're using something defined for you by the implementation). If you want to generate an identifier from an existing one, trailing underscores are ok. > void _perform_action(int actCd, const char * file, int lineno) { > printf("Called perform_action from %s:%d\n", file, lineno); > } > > > int main(void) { > perform_action(4); > return 0; > } Otherwise, that looks reasonable. It's a lot of extra work, it only goes up one level (going up arbitrarily many levels is going to be interesting), and it only works for functions for which you specifically provide the feature. The most likely reason you'd want this information is for debugging. In that case, a good source-level debugger should give you that information and a lot more as well. If you want the behavior of the function to vary depending on where it's called from, that's almost certainly a bad idea, better implemented by just passing an extra argument to control the behavior. As with a lot of low-level stuff like this, the first thing you should do is step back and decide what problem you're actually trying to solve. It's likely that there's a better and/or more portable solution. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. |
Re: Function invocation location
1.41421@gmail.com writes:
> Keith Thompson wrote: >> 1.41421@gmail.com writes: >> > I was wondering if it would be possible to find out, from within a >> > function, the file and line number where that particular function call >> > was invoked, bearing in mind that the function can potentially be >> > invoked from many different files. I guess that what I am looking for >> > is something similar to the __FILE__ and __LINE__ symbols, but one >> > level up in the function call stack. >> >> No, there's no good portable way to do that. >> >> You could probably do something involving passing extra arguments to >> your functions, but it wouldn't be pretty. >> >> A source level debugger should be able to show this information >> interactively. >> >> What are you trying to accomplish? > > Pretty much what I said: To find out who is invoking a certain > function, and at what point. I am using an embedded environment, and a > source level debugger does disturb things so that what I am trying to > see is not there anymore. The only way I could think of to do it is by > means of the info above, and well-placed printf (the output of which > goes to a console accessible through a serial port). If a source level debugger masks the problem, it's likely that either the debugger is broken or you're dealing with undefined behavior. You can do what you want by changing your code, but that's also likely to disturb things. (It's worth a try, though.) If you know how the compiler lays out stack frames, you *might* be able to display the return address in, say, hexadecimal, and map that back to the point at which the function was called. This is clearly *extremely* system-specific, so we can't really go into it here, but it might give you what you need. -- Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> We must do something. This is something. Therefore, we must do this. |
Re: Function invocation location
castillo.bryan@gmail.com wrote:
> I use macros to do it > > > > #include <stdio.h> > > #define perform_action(a) _perform_action((a),__FILE__,__LINE__) > void _perform_action(int actCd, const char * file, int lineno); > > > void _perform_action(int actCd, const char * file, int lineno) { > printf("Called perform_action from %s:%d\n", file, lineno); > } > > > int main(void) { > perform_action(4); > return 0; > } Would this not stop working if, instead of using the name of the function itself, one invokes it via a pointer? |
Re: Function invocation location
Keith Thompson a écrit :
[snip] > If a source level debugger masks the problem, it's likely that either > the debugger is broken or you're dealing with undefined behavior. It is impossible for a debugger to mask itself completely. Having written a debugger for embedded systems I can tell you, the debugger is a BIG mess that comes upon your poor program. Impossible to do otherwise in cramped conditions, no RAM, no MMU, etc. That the program has "undefined behavior" is obvious, if not he would not be trying to debug !!! > You > can do what you want by changing your code, but that's also likely to > disturb things. (It's worth a try, though.) > I agree with you in this. The printfs do CHANGE things, and even if the impact is smaller than the impact of the debugger, they DO CHANGE the program, as you said. > If you know how the compiler lays out stack frames, you *might* be > able to display the return address in, say, hexadecimal, and map that > back to the point at which the function was called. This is clearly > *extremely* system-specific, so we can't really go into it here, but > it might give you what you need. > That is the best solution for this problem. Find out how the compiler lays out the stack frame (an assembly listing will do that) and try to send the hexadecimal return address through the serial line. With the help of a link map, you can figure out where you were called from. jacob |
Re: Function invocation location
Keith Thompson wrote:
> 1.41421@gmail.com writes: > > Keith Thompson wrote: > >> 1.41421@gmail.com writes: > >> > I was wondering if it would be possible to find out, from within a > >> > function, the file and line number where that particular function call > >> > was invoked, bearing in mind that the function can potentially be > >> > invoked from many different files. I guess that what I am looking for > >> > is something similar to the __FILE__ and __LINE__ symbols, but one > >> > level up in the function call stack. > >> > >> No, there's no good portable way to do that. > >> > >> You could probably do something involving passing extra arguments to > >> your functions, but it wouldn't be pretty. > >> > >> A source level debugger should be able to show this information > >> interactively. > >> > >> What are you trying to accomplish? > > > > Pretty much what I said: To find out who is invoking a certain > > function, and at what point. I am using an embedded environment, and a > > source level debugger does disturb things so that what I am trying to > > see is not there anymore. The only way I could think of to do it is by > > means of the info above, and well-placed printf (the output of which > > goes to a console accessible through a serial port). > > If a source level debugger masks the problem, it's likely that either > the debugger is broken or you're dealing with undefined behavior. You > can do what you want by changing your code, but that's also likely to > disturb things. (It's worth a try, though.) There are some timing considerations that the debugger interferes with in an unavoidable way. On the other hand, a few printf statements do not disturb such considerations significantly. > If you know how the compiler lays out stack frames, you *might* be > able to display the return address in, say, hexadecimal, and map that > back to the point at which the function was called. This is clearly > *extremely* system-specific, so we can't really go into it here, but > it might give you what you need. > > -- > Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> > San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst> > We must do something. This is something. Therefore, we must do this. |
| All times are GMT. The time now is 08:26 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.