why does assert(0) corrupt the stack trace?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

why does assert(0) corrupt the stack trace?

慕冬亮
Hi all,

I have a question about debugging assert in gdb. When one program
crash at one assert statement, the stack trace shown in the gdb is
corrupted. Is it normal?

--
My best regards to you.

     No System Is Safe!
     Dongliang Mu
Reply | Threaded
Open this post in threaded view
|

Re: why does assert(0) corrupt the stack trace?

Paul Smith-43
On Sun, 2017-11-05 at 14:13 -0500, 慕冬亮 wrote:
> I have a question about debugging assert in gdb. When one program
> crash at one assert statement, the stack trace shown in the gdb is
> corrupted. Is it normal?

No, that's not normal.

Cheers!
Reply | Threaded
Open this post in threaded view
|

Re: why does assert(0) corrupt the stack trace?

Jan Kratochvil-2
In reply to this post by 慕冬亮
On Sun, 05 Nov 2017 20:13:20 +0100, 慕冬亮 wrote:
> I have a question about debugging assert in gdb. When one program
> crash at one assert statement, the stack trace shown in the gdb is
> corrupted. Is it normal?

It was happening in the past as when assert() detects a failure it calls
abort() which does never return - using GCC attribute noreturn.  Then GCC
optimizer does not save enough registers to make the backtrace possible
because the code will just abort anyway, the code does not need to know where
to return.

It was some intermediate development phase where such optimization was created
and before an exception has been made to make the backtracing by debuggers
possible.

Sorry for not looking up the Bugs/commits.

As usual you should update your compiler + debugger to latest versions.


Jan
Reply | Threaded
Open this post in threaded view
|

Re: why does assert(0) corrupt the stack trace?

慕冬亮
--
My best regards to you.

     No System Is Safe!
     Dongliang Mu


2017-11-05 14:54 GMT-05:00 Jan Kratochvil <[hidden email]>:

> On Sun, 05 Nov 2017 20:13:20 +0100, 慕冬亮 wrote:
>> I have a question about debugging assert in gdb. When one program
>> crash at one assert statement, the stack trace shown in the gdb is
>> corrupted. Is it normal?
>
> It was happening in the past as when assert() detects a failure it calls
> abort() which does never return - using GCC attribute noreturn.  Then GCC
> optimizer does not save enough registers to make the backtrace possible
> because the code will just abort anyway, the code does not need to know where
> to return.
>
If I compile the program with "-O0", this problem may be solved. Yes?

> It was some intermediate development phase where such optimization was created
> and before an exception has been made to make the backtracing by debuggers
> possible.
>
> Sorry for not looking up the Bugs/commits.
>
> As usual you should update your compiler + debugger to latest versions.
>
>
> Jan
Reply | Threaded
Open this post in threaded view
|

Re: why does assert(0) corrupt the stack trace?

Jan Kratochvil-2
On Sun, 05 Nov 2017 21:05:04 +0100, 慕冬亮 wrote:
> If I compile the program with "-O0", this problem may be solved. Yes?

You would need to recompile glibc with -g -O0.  Which I am not sure if it is
even possible.


Jan
Reply | Threaded
Open this post in threaded view
|

Re: why does assert(0) corrupt the stack trace?

Duane Ellis-3
In reply to this post by 慕冬亮

> On Nov 5, 2017, at 12:05 PM, 慕冬亮 <[hidden email]> wrote:
>
> If I compile the program with "-O0", this problem may be solved. Yes?

Often with “-O0” (dash OH zero, turning the optimizer off) helps this is the most direct route to try to determine what went wrong.

However - it depends on what went wrong, for example if your application has a buffer overflow on the stack, and that buffer overflow corrupted the stack - or other memory was corrupted the stack back trace might as a result be corrupt

Or - the problem might change/move when you disable the optimizer the code changes, the number of registers allocated per function changes, etc ...

That said, the most direct and most common thing to do is to disable the optimizer and try again.

If you get desperate and the above does not help you might try unwinding the stack by hand - it takes a while and often you can do what the compiler & debugger cannot do.

This approach trys to understand where the application was, and what it was doing when the crash occurred - sometimes you can inspect memory at or near the stack, and manually unwind the stack by inspecting various values stored on the stack.

For example, on a 32bit machine - dump the stack memory near the stack pointer (ie: +/- 512 bytes) as 32bit values - then look at each value and see if they align with addresses within your application where subroutine calls occur.  (Ie:  Use “objdump -d MYAPP” to get a disassembly listing of your app)

It is painful but sometimes it is the only way.

-Duane.