Re: reliable reproducer, was Re: core dump analysis

Michael Schmitz
2023-04-24T05:46:29Z

Hi Finn,

Am 24.04.2023 um 15:51 schrieb Michael Schmitz:
> Hi Andreas,
>
> On 24/04/23 09:48, Andreas Schwab wrote:
>> On Apr 24 2023, Michael Schmitz wrote:
>>
>>> Not sure what third argument you referred to in another mail.
>> See struct sigframe and struct rt_sigframe. The non-rt signal handler
>> gets signal number, vector number and sigcontext*. The rt signal
>> handler gets signal number, siginfo* and ucontext*.
>
> Thanks, I see now. Got confused by the sigaction man page (despite
> working out that it's all there on the stack before...). Might need a
> comment in the code (or an update to the man pages).
>
> I've rewritten my test program to make the non-rt handler take three
> arguments, just to simplify things. Also fixed the end of signal frame
> calculation for the non-rt case where the exception places additional
> data on the stack.
>
> Running with the non-rt handler, the crash appears to happen right at
> the end of the recursion (or at least, I take no further SIGCHLD on the
> way back up the stack). With the rt handler, I see the stack depth
> decreased on the last signal taken before the crash.
>
> When I enable dumping the extra exception frame contents (which will
> show prior stack contents when the exception only used a four-word
> frame) in the rt handler case, I only see saved register data placed
> there at the very end. That's different from previous tests where I saw
> the saved register patterns all the time. (but might have had the
> offsets wrong).
>
> I'll see what peeking at the registers shows (now that I can be
> confident I have got the offsets correct).

Last two signals received before core dump below:

stack depth : 197952
retn. depth : 200000
parent usp : 0xef933eb8
signal stack overwrote parent usp!
frame end : 0xef933f1c
frame start : 0xef933bf8
handler usp : 0xef933be0
signal usp : 0xef933ea8
signal pc : 0xc009f37a

signal stack: 0x80004050
signal usp : 0xef933ea8
signal pc : 0xc009f37a
signal f.d1 : 0x0
signal f.d2 : 0x0
signal f.d3 : 0x0
signal f.d4 : 0x0
signal f.d5 : 0x0
signal f.a0 : 0x0
signal f.a1 : 0x0
signal f.a2 : 0x0
signal f.d0 : 0x0
signal f.od0: 0x0
signal f.sad: 0x0
signal f.sr : 0x0
signal f.pc : 0x0
signal fmtv : 0x80
signal a2 : 0x91929394
signal a3 : 0xa1a2a3a4
signal a4 : 0xb1b2b3b4
signal a5 : 0xc0104e0c
signal d2 : 0xd1d2d3d4
signal d3 : 0xe1e2e3e4
signal d4 : 0xf1f2f3f4

stack depth : 200000
retn. depth : 193942
parent usp : 0xef921edc
signal stack overwrote parent usp!
frame end : 0xef95733c
frame start : 0xef957018
handler usp : 0xef957000
signal usp : 0xef9572c4
signal pc : 0x8000073a

signal stack: 0x80004050
signal usp : 0xef9572c4
signal pc : 0x8000073a
signal f.d1 : 0xa1a2a3a4
signal f.d2 : 0xb1b2b3b4
signal f.d3 : 0xc1c2c3c4
signal f.d4 : 0xef957250
signal f.d5 : 0x80000722
signal f.a0 : 0xd1d2d3d4
signal f.a1 : 0xe1e2e3e4
signal f.a2 : 0xf1f2f3f4
signal f.d0 : 0x91929394
signal f.od0: 0xa1a2a3a4
signal f.sad: 0xb1b2b3b4
signal f.sr : 0xc1c2c3c4
signal f.pc : 0xef957274
signal fmtv : 0x114
signal a2 : 0x91929394
signal a3 : 0xa1a2a3a4
signal a4 : 0xb1b2b3b4
signal a5 : 0xc1c2c3c4
signal d2 : 0xd1d2d3d4
signal d3 : 0xe1e2e3e4
signal d4 : 0xf1f2f3f4

Illegal instruction (core dumped)

What I thought would hold the copies of pt_regs and switch_stack remains
empty while on the way down the stack, and is filled with saved
registers when on the way back up.

The registers as saved on exception, and copied to the mcontext struct,
are correct in all cases, except for a5 which often contains 0xc0104e0c.
Whenever that happens, a trap exception did get us into kernel mode. On
both page faults and interrupts, a5 is as stored there (0xc1c2c3c4).

usp stored in the signal frame (i.e. usp when the signal was taken) is
0x10 below that saved at the start of rec(). That's not enough to store
7 registers plus return pc...

I still seem to have the sigframe end address wrong - it's larger than
both parent usp and usp stored in the sigframe.

Still baffled.

Cheers,

Michael