Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to get information from call-stack?

0 views
Skip to first unread message

Zsolt Zsoldos

unread,
Jan 16, 2001, 5:39:55 PM1/16/01
to
Hi All,

I'm writing a C++ template class for generic pointers with range checking.
I got it working fine, but my problem is, when it detects range error,
it would be very useful to be able to report where it occured in the soruce.
I know about the __FILE__ and __LINE__ macro definitions, but they cannot
be used in this case, because the problem is being detected inside an
operator method of the template pointer class (e.g. operator* or operator[]).

However, the information I need is stored in the call-stack, e.g. if I
abort() the code, then postmortem debugging could reveal where it was called
from (the call stack contains the function name, file name and line number
of the caller). Now, I'd like to extract that information from the stack
inside the code, i.e. write an error/log message which prints out that
information.

If there is no standard C++ way to do this (which I suspect is the case),
then I would be most interested in a solution for GNU g++ (v2.95.3) on Linux
or for MIPSPro C++ v7.2.1 on SGI Irix.

Any ideas, suggestions, information pointers about this topic are greatly appreciated!

Thanks a lot,
--
Zsolt Zsoldos

Ron Natalie

unread,
Jan 16, 2001, 5:46:35 PM1/16/01
to

Zsolt Zsoldos wrote:
>
> If there is no standard C++ way to do this (which I suspect is the case),
> then I would be most interested in a solution for GNU g++ (v2.95.3) on Linux
> or for MIPSPro C++ v7.2.1 on SGI Irix.

You are right, there is no standard way to do it.
If you find out how to do it for G++ let me know.

Flavius Vespasian

unread,
Jan 16, 2001, 6:42:37 PM1/16/01
to

I'd suggestion something along the lines of examining a core dump in a
debugger.

John - N8086N
Big brother is watching. Disable cookies in your web browser.
-------------------------------------------
Wise man says "Never use a bank with the initials F. U."
-------------------------------------------
Are you interested in a professional society or
guild for programmers? Want to fight section 1706?


See www.programmersguild.org
Newsgroup: us.issues.occupations.computer-programmers


EMail Address:
_m-i-a-n-o_@_c_o_l_o_s_s_e_u_m_b_u_i_l_d_e_r_s._c_o_m_


Ron Natalie

unread,
Jan 17, 2001, 10:14:00 AM1/17/01
to

Flavius Vespasian wrote:
>
> >If there is no standard C++ way to do this (which I suspect is the case),
> >then I would be most interested in a solution for GNU g++ (v2.95.3) on Linux
> >or for MIPSPro C++ v7.2.1 on SGI Irix.
> >
> >Any ideas, suggestions, information pointers about this topic are greatly
> > appreciated!
>
> I'd suggestion something along the lines of examining a core dump in a
> debugger.

Well, peaking at the debugger source is probably the place to start, but
some of us, need to handle diagnostics short of actually generating a core
file.

Mike Holder

unread,
Jan 17, 2001, 2:08:25 PM1/17/01
to

There is certainly no standard C++ way to do this, and no particularly
easy way to program this, either, although I suppose it could be done.

A. Unless you caused explicit file and linenumber info to be pushed on
the call stack, it isn't there. No C/C++ compiler I've seen
generates
that for you. There is return address information there, and that
can be mapped into file/linenumber with some effort. You would need
the symbol table information from your running process (presumably
in your executable file, but you'd have to tell the compiler to
generate it as well (and it can make your executables HUGE)). You
could then do lookups of return addresses and convert them into
function names and offsets and/or filenames and linenumbers. This
is the same kind of code that debuggers use when they do symbolic
stack traces. (You'll need to know what object file format the
symbol table is in, and you'd have to use the correct library calls
to access the symbol table.)

B. You can write fairly simple (< 10 lines) code that does non-symbolic
stack traces. You wouldn't get filename/linenumber (or even function
name/offset), but you do those conversions manually if you needed to
(via some tool like 'nm'). However, its a little tricky to write
really _portable_ stack traversing code for several reasons:
1. on some architectures, stacks grow up; on others, they grow down
2. function call linkage conventions are different for different
architectures and different compilers (and in fact, there can be
multiple function call linkages available in a single compiiler
using various command line flags). Some architectures put return
address (and/or parameters) on the stack, so use registers. It's
a little tricky for the code to determine the linkage call
conventions at execution time if there are multiple possibilities.

Someone suggested just causing the process to dump core and then use a
debugger (gdb or whatever) on the coredump file. That might be the
easiest thing to do. Of course, having your process trap and die
might not be acceptible. If not, then write your own non-symbolic
stack trace routine (probably ifdef'd for Linux (Intel?) and Irix
(SGI)).

I do seem to remember some open source function/utility called something
like gstack that would generate stack traces (at least for Intel
platforms).
I forget whether it did symbolic lookups (I think it did, maybe only for
ELF-formatted object files). Try hunting around the WWW for that.
(There's
also a FreeBSD program called gcore that can be used to generate a
coredump file on a running process (without killing it). You might be
able to use that as well. (I think they were both C code.)

Mike

--
----------------------------------------------------
Mike Holder
Lucent Technologies voice: (919) 838-5647
Room 452B email: mlho...@lucent.com
1801 Varsity Drive WWW: TBD
Raleigh, NC 27606 fax: (919) 838-5640

Zsolt Zsoldos

unread,
Jan 17, 2001, 3:57:00 PM1/17/01
to
Mike, thank you very much for the suggestions!
I will try to work out something, but in the meantime I'd like to
share with you the information I have found in the book titled
"Professional Linux Programming" written by many people, but the
two main authors are Neil Matthew and Richard Stones. So the solution
they offer for Linux 2.2 or above with GNU C/C++ 2.95.1 and above:

#include <execinfo.h>

...

#define MAX_STACK 100

...
void dumptrace()
{
static void *addresses[MAX_STACK];
int n = backtrace( addresses, MAX_STACK );
char **names = backtrace_symbols( addresses, n );
for ( int i = 0; i < n; i++ )
{
LOG_MESS( "location["<<i<<"]="<<names[i] );
}
free( names );
}

One could also use backtrace_symbols_fd instead of backtrace_symbols,
that would print the symbolic information into a file without allocating
an extra buffer for it. The file has to be open for writing.

The book also suggest a portable way to get at least function level
information (not exact line numbers) with some extra work, i.e. to use
a macro for tracing all function calls and returns explicitly in the
code - practically maintaning your own call-stack.

Thanks again,
--
Zsolt Zsoldos, zs...@simbiosys.ca, http://www.simbiosys.ca/

0 new messages