Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Backtrace function

Reply
Thread Tools

Backtrace function

 
 
Ian Collins
Guest
Posts: n/a
 
      03-28-2008
Richard Heathfield wrote:
> jacob navia said:


>> No, In non portable C you can do it

>
> You mis-read what he wrote, which is that there is no way (even a
> non-portable way) to do it in *standard* C.
>
>> 1) Read the frame pointer (This is the only assembly yo need)

>
> And Step 1 is where it stops being standard C.
>
> <snip>
>
>> 5) Find out into which function the return address points to.
>>
>> 6) Is that the function "main"?
>>
>> 7) If not, get the next frame pointer and go to (2)

>
> This fails to handle recursive calls to main.
>

Which occur how often?

I know it isn't standard C, but I've added code to a couple of embedded
systems that does almost exactly what Jacob describes. It may not be
standard C, but it might help someone who wants to know how.

--
Ian Collins.
 
Reply With Quote
 
 
 
 
jacob navia
Guest
Posts: n/a
 
      03-28-2008
Ian Collins wrote:
> Richard Heathfield wrote:
>> jacob navia said:

>
>>> No, In non portable C you can do it

>> You mis-read what he wrote, which is that there is no way (even a
>> non-portable way) to do it in *standard* C.
>>
>>> 1) Read the frame pointer (This is the only assembly yo need)

>> And Step 1 is where it stops being standard C.
>>
>> <snip>
>>
>>> 5) Find out into which function the return address points to.
>>>
>>> 6) Is that the function "main"?
>>>
>>> 7) If not, get the next frame pointer and go to (2)

>> This fails to handle recursive calls to main.
>>

> Which occur how often?


But it DOES handle recursive calls. It will just stop at the
first of those recursive calls since it looks no further up!

>
> I know it isn't standard C, but I've added code to a couple of embedded
> systems that does almost exactly what Jacob describes. It may not be
> standard C, but it might help someone who wants to know how.
>


Exactly, that is what I wanted to show. The frame pointers are just
a linked list. Immediately above (in most cases)
is the return address, and there you go!


--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      03-28-2008
jacob navia said:

> Richard Heathfield wrote:
>> jacob navia said:
>>

<snip>

>>> No, In non portable C you can do it

>>
>> You mis-read what he wrote, which is that there is no way (even a
>> non-portable way) to do it in *standard* C.
>>
>>> 1) Read the frame pointer (This is the only assembly yo need)

>>
>> And Step 1 is where it stops being standard C.

>
> Why?
>
> It means calling
>
> fp = GetFramePointer();
>
> And that is standard C.


Ha! Yes, we're right on the border here. Clearly, the *call* is standard.
The implementation of GetFramePointer() is not, *but* the claim was that
there was no way to do this non-portably in standard C. Standard C
implementations can legally offer extensions, and non-portable programs
can take advantage of them whilst remaining syntactically
standard-conforming. I think you win this round. Nice one.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      03-28-2008
Flash Gordon wrote:
> jacob navia wrote, On 28/03/08 21:39:
>
>> 2) See at what offset from the frame pointer is the pushed return
>> address

>
> If there is anything to tell you other than the function prologue. Of
> course the return address might not have been saved to RAM either due to
> function inlining (as an optimisation) or because it did not need to for
> some other reason.
>

Interesting point, if your coding style is anything like mine, you will
have lots of small functions that do get inlined, leaving a pretty
useless call stack

>> 3) The value stored in the saved frame pointer position points to
>> the next frame.

>
> If there is a saved frame pointer. Not all implementations use a
> separate frame pointer.
>

x64 is a prime example, very difficult even for a debugger to work out
the callstack in optimised code.

--
Ian Collins.
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      03-28-2008
Flash Gordon wrote:
> jacob navia wrote, On 28/03/08 21:39:
>> Kaz Kylheku wrote:
>>> On Mar 28, 12:47 pm, Keith Thompson <(E-Mail Removed)> wrote:
>>>> sophia <(E-Mail Removed)> writes:
>>>>> can any one suggest ways of implementing a backtrace function in ANSI/
>>>>> standard C as given in the following link ?
>>>>> http://pramode.net/2006/09/12/gettin...running-c-code...
>>>>>
>>>> There's no portable way to do that in standard C.
>>>
>>> Also, there is no nonportable way to do that in standard C, either.
>>>
>>>

>>
>> No, In non portable C you can do it

>
> Sometimes. Sometimes you can't.
>
>> 1) Read the frame pointer (This is the only assembly yo need)

>
> If there is one.
>


Mr "Gordon":
I said this several lines below. Please read the whole message
before replying.

I have the feeling that you do not red the message and try to
understand what I propose but that you jump into each sentence
trying to find out something to comment negatively on.

>> 2) See at what offset from the frame pointer is the pushed return
>> address

>
> If there is anything to tell you other than the function prologue. Of
> course the return address might not have been saved to RAM either due to
> function inlining (as an optimisation) or because it did not need to for
> some other reason.
>


The function address is always saved, or, sometimes held in a
designated register. In both cases it is at a fixed point.

Obviously, if your function is *inlined* it will NOT appear
in a backtrace of the stack!

But that is "by design" isn't it?




>> 3) The value stored in the saved frame pointer position points to
>> the next frame.

>
> If there is a saved frame pointer. Not all implementations use a
> separate frame pointer.
>


See the prerequisites that I wrote below...


>> Here you have the next frame and the address of some point in the
>> calling procedure.

>
> Maybe, if all your assumtions are true so far.
>
>> 4) Read the debug information.

>
> If there is any which there might not be.
>


If there is no debug information, a backtrace can still be
printed, but it is a backrace like:

0x4477ADD()
0x4477665()

etc

The address can be still useful if you have a linker map.


>> 5) Find out into which function the return address points to.
>>
>> 6) Is that the function "main"?
>>
>> 7) If not, get the next frame pointer and go to (2)

>
> A problem if main was called recursively.
>


No. As I explained to Mr Heathfield, that raised the same objection,
my algorithm just stops at the first possible recursive call of main
It doesn't fail at all. It will not follow recursive calls to "main".

That is all.

Obviously, calling "main" recurisvely is very popular here.



>> ---------------
>>
>> This supposes that
>>
>> (1) you have a frame pointer
>> (2) The calling function has a frame pointer
>>


You see?

If you would have read till here, you would have saved yourself
the remarks above.

>> GDB is written in C, and the lcc-win debugger is
>> written in C. So there is OBVIOUSLY a way of doing
>> this in C!

>
> No, obviously under some specific circumstances it is possible but it is
> not always possible or if it is then might be more complex than you have
> suggested.


Mr "Gordon"
Writing a debugger is more complex than what I outlined above.

True.

And so what?

The purpose of my algorithm description is not to provide you
with a ready made debugger implementation!

Specially

"Read all debug information" is quite complex as an undertaking,
I can tell you.



--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      03-28-2008
Ian Collins wrote:
> Flash Gordon wrote:
>> jacob navia wrote, On 28/03/08 21:39:
>>
>>> 2) See at what offset from the frame pointer is the pushed return
>>> address

>> If there is anything to tell you other than the function prologue. Of
>> course the return address might not have been saved to RAM either due to
>> function inlining (as an optimisation) or because it did not need to for
>> some other reason.
>>

> Interesting point, if your coding style is anything like mine, you will
> have lots of small functions that do get inlined, leaving a pretty
> useless call stack
>
>>> 3) The value stored in the saved frame pointer position points to
>>> the next frame.

>> If there is a saved frame pointer. Not all implementations use a
>> separate frame pointer.
>>

> x64 is a prime example, very difficult even for a debugger to work out
> the callstack in optimised code.
>


Yes, my debugger has still problems even with slightly
optimized code.

The first 4 arguments are not in the stack, but in
RCX,RDX,R8,and R9.

Sometimes I optimize the writing of those registers
and skip any stores. This confuses the debugger completely.

I tried to emit in the compiler, records to tell the debugger
in which registers the variable lives, but since I alias
a register to several variables at the same time if possible
(when the variables have disjoint lifetimes) that is a further
complication.

In any case for the straight backtrace there is no problem since
lcc-win ALWAYS emits a frame pointer.

I thought that for the time being, I will emit frame pointers until
I find a way of telling the debugger where the return address should
be. If not, you just can't debug optimized code!

There was recently a discussion in the gcc mailing list about the
updating of the debug information to support optimized code.

I had the impression that the poor guy that tried to do that didn't
receive much support from the compiler people, maybe because everyone
ws convinced that the task is just too difficult and would
imply a lot of modifications in the compiler.

I will try to avoid that situation. I prefer slower code but
code that can be debugged, sorry. Specially in x64, the
machines are so fast that making the code undebuggable is
just not worth the price you pay for it in undiscovered bugs!


--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      03-28-2008
jacob navia said:

> Flash Gordon wrote:
>> jacob navia wrote, On 28/03/08 21:39:

<snip>
>
>>> 5) Find out into which function the return address points to.
>>>
>>> 6) Is that the function "main"?
>>>
>>> 7) If not, get the next frame pointer and go to (2)

>>
>> A problem if main was called recursively.
>>

>
> No. As I explained to Mr Heathfield, that raised the same objection,
> my algorithm just stops at the first possible recursive call of main
> It doesn't fail at all. It will not follow recursive calls to "main".
>
> That is all.
>
> Obviously, calling "main" recurisvely is very popular here.


Well, not really, but recursive main *is* legal. It seems to me that a
non-portable solution would be free to learn main's caller (e.g. _startup,
or whatever), and probe for that instead. This would allow recursive main
calls to be backtraced properly.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
jacob navia
Guest
Posts: n/a
 
      03-28-2008
Richard Heathfield wrote:
> jacob navia said:
>
>> Flash Gordon wrote:
>>> jacob navia wrote, On 28/03/08 21:39:

> <snip>
>>>> 5) Find out into which function the return address points to.
>>>>
>>>> 6) Is that the function "main"?
>>>>
>>>> 7) If not, get the next frame pointer and go to (2)
>>> A problem if main was called recursively.
>>>

>> No. As I explained to Mr Heathfield, that raised the same objection,
>> my algorithm just stops at the first possible recursive call of main
>> It doesn't fail at all. It will not follow recursive calls to "main".
>>
>> That is all.
>>
>> Obviously, calling "main" recurisvely is very popular here.

>
> Well, not really, but recursive main *is* legal. It seems to me that a
> non-portable solution would be free to learn main's caller (e.g. _startup,
> or whatever), and probe for that instead. This would allow recursive main
> calls to be backtraced properly.
>
> <snip>
>


In principle you are right, and I considered that. Problem is, my
startup is obviously not written in C but in assembler... It would
have been quite impossible to write it in C actually...

In my context, My assembler doesn't know how to emit debug information,
so there is no debug info.

For startups written in C, your idea would work.

--
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      03-29-2008
jacob navia wrote:
> Richard Heathfield wrote:
>> jacob navia said:
>>

.... snip ...
>>
>>> 1) Read the frame pointer (This is the only assembly yo need)

>>
>> And Step 1 is where it stops being standard C.

>
> Why? It means calling
>
> fp = GetFramePointer();
>
> And that is standard C.


I think you had better return your C book, and your copy of the C
standard, for refunds. Someone has been passing off invalid copies
on you.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.



--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      03-29-2008
CBFalconer said:

> jacob navia wrote:


<snip>

>> fp = GetFramePointer();
>>
>> And that is standard C.

>
> I think you had better return your C book, and your copy of the C
> standard, for refunds. Someone has been passing off invalid copies
> on you.


Consider the following code:

x = y();

Is that standard C? If not, why not?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
symbol table for backtrace cgable2003@gmail.com C Programming 3 11-26-2007 09:36 PM
Backtrace / crash report on segfault w/o user interaction NeoTrantor C++ 2 03-30-2007 09:23 AM
Getting backtrace on an axception Paolo Pantaleo Python 0 06-10-2006 05:24 PM
backtrace forwarded email's recipients septer2006@hotmail.com Computer Security 0 05-23-2006 03:40 PM
Coredump/backtrace Rafal 'Raf256' Maj C Programming 2 04-12-2005 01:33 PM



Advertisments