Arm64 stack issues (was Re: FreeBSD status for/on ODroid-C2?)

Mark Millard markmi at dsl-only.net
Thu Feb 9 05:20:32 UTC 2017


Another sh core, this one with non-zero "junk" around
the sp at the core-dump gives new information. The "junk"
is because the SP actually ends up in higher addressed
memory than the base frame (when .rtld_start does
"bl _rtld"). [Some sh core dumps have different sp
relationships than this but this can and does
happen.]

With the below additional evidence I conclude that
either the stack pointer was messed up when fork
returned for the child path or shortly there after
(while sh's forkshell routine was still active).





Supporting details:

General Purpose Registers:
. . .
        sp = 0x0000ffffffffe600

The sp = 0x0000ffffffffe600 is rather high in memory,
in fact outside the stack for what ld-elf.so.1`.rtld_start
calls. . .

0xffffffffd5b0: 0x0000ffffffffd5f0 0x0000000000402f30
0xffffffffd5c0: 0x0000000000000000 0x0000000000000000
0xffffffffd5d0: 0x0000000000000000 0x0000000000000000
0xffffffffd5e0: 0x0000ffffffffd600 0x0000ffffffffd600
0xffffffffd5f0: 0x0000000000000000 0x0000000040434658

(Note: 0x0000ffffffffe600-0x1000==0xffffffffd5f0+0x10
 but other core files have widely varying distances.)

For that last line:

0xffffffffd5f0: 0x0000000000000000 0x0000000040434658
(lldb) dis -s -4*4+0x0000000040434658
ld-elf.so.1`.rtld_start:
    0x40434648 <+8>:  sub    sp, sp, #0x10             ; =0x10 
    0x4043464c <+12>: mov    x1, sp
    0x40434650 <+16>: add    x2, x1, #0x8              ; =0x8 
    0x40434654 <+20>: bl     0x2e4c                    ; _rtld at rtld.c:339
    0x40434658 <+24>: mov    x8, x0

(0x2e4c is not in the core file.)

and for the other frame-pointer/lr-value pair:

0xffffffffd5b0: 0x0000ffffffffd5f0 0x0000000000402f30
(lldb) dis -s -4*4+0x0000000000402f30
sh`__start:
    0x402f20 <+344>: mov    w0, w21
    0x402f24 <+348>: mov    x1, x20
    0x402f28 <+352>: mov    x2, x19
    0x402f2c <+356>: bl     0x410c14                  ; main at main.c:97
    0x402f30 <+360>: bl     0x402ae0                  ; symbol stub for: exit

Note: Anything higher addressed in memory than that 
0xffffffffd5ff I'll say is "higher than the stack
region" or some such phrase.

Yet despite being higher than the stack region
there are some stack frames also near by (also
higher than the stack region). . .

An area around the sp = 0x0000ffffffffe600 that lldb
reported for this core (with some notes used later):

. . .
0xffffffffe400: 0x6572662d6e776f6e 0x302e323164736265
0xffffffffe410: 0x56454c454b414d00 0x42494c00323d4c45
0xffffffffe420: 0x403d434e49464c45 0x6e69666c6562696c
0xffffffffe430: 0x4f465f444c004063 0x5445475241545f52
0xffffffffe440: 0x6f6c2f7273752f3d 0x637261612f6c6163
0xffffffffe450: 0x656e6f6e2d343668 0x6e69622f666c652d
0xffffffffe460: 0x3d62647000646c2f 0x2f62642f7261762f
0xffffffffe470: 0x74726f7000676b70 0x2f3d72696462645f
0xffffffffe480: 0x702f62642f726176 0x5f4d50007374726f
0xffffffffe490: 0x505f544e45524150 0x657665643d54524f
0xffffffffe4a0: 0x3668637261612f6c 0x652d656e6f6e2d34
0xffffffffe4b0: 0x43006363672d666c 0x5243530063633d43
0xffffffffe4c0: 0x6f6f722f3d545049 0x5f7374726f702f74
0xffffffffe4d0: 0x0000000000000078 0x637261612f737470 ("junk" (text) temporarily stops here)
0xffffffffe4e0: 0x00000000004345c8 0x0000000000434000 (beginning of what looks like stack frames)
0xffffffffe4f0: 0x0000000000434000 0x0000000040a903e0
0xffffffffe500: 0x0000ffffffffe540 0x000000004054cd94
0xffffffffe510: 0x696d6b72616d2f6c 0x0000000000000000
0xffffffffe520: 0x0000000000000000 0x0000000000000000
0xffffffffe530: 0x0000000000000000 0xe8021690dc1f70b8
0xffffffffe540: 0x00000000004345c8 0x0000000000434000
0xffffffffe550: 0x0000000000434000 0x000000000000000f
0xffffffffe560: 0x0000ffffffffe5a0 0x000000000041aef0
0xffffffffe570: 0x0000000000434c38 0x732f7273752f3a6e
0xffffffffe580: 0x0000000000000001 0x0000000000000005
0xffffffffe590: 0x0000000040a33180 0x0000000000000000
0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490 ("junk" (text) starts again after this line)
0xffffffffe5b0: 0x54494445003d4854 0x41500069763d524f x26, x25 values (see below)
0xffffffffe5c0: 0x2f3d534547414b43 0x74726f702f727375 x24, x23 values (see below)
0xffffffffe5d0: 0x67616b6361702f73 0x414c46444c007365 x22, x21 values (see below)
0xffffffffe5e0: 0x58584300203d5347 0x662d3d5347414c46 x20, x19 values (see below)
0xffffffffe5f0: 0x2d74656b63617262 0x31353d6874706564  fp,  lr values (see below); pc==lr eventually.
0xffffffffe600: 0x346d673d344d0032 0x73752f3d564e4500
0xffffffffe610: 0x6d2f656d6f682f72 0x732e2f696d6b7261
0xffffffffe620: 0x2f3d647000637268 0x74726f702f727375
0xffffffffe630: 0x4441524750550073 0x703d4c4f4f545f45
0xffffffffe640: 0x657473616d74726f 0x5254524f46470072
0xffffffffe650: 0x4552534f003d4e41 0x4f00302e32313d4c
0xffffffffe660: 0x752f3d445750444c 0x702f6a626f2f7273
. . .

So at this point we have that the stack pointer was
messed up somewhat prior to the core-dump.

x19-x26 in the below are from the locations indicated
to the side above:

General Purpose Registers:
        x0 = 0x0000000000000000
        x1 = 0x0000000000000000
        x2 = 0x0000000000000000
        x3 = 0x00000000405735c8  libc.so.7`__sys_sigaction
        x4 = 0x0000000000000090
        x5 = 0x2080002000200000
        x6 = 0x0000000000434c28  sh..bss + 9448
        x7 = 0x00000000000c590d
        x8 = 0x0000000000000000
        x9 = 0x0000000000000000
       x10 = 0x0000000000434000  sh..bss + 6336
       x11 = 0x0000000000000000
       x12 = 0x0000000000434c38  sh..bss + 9464
       x13 = 0x0000000000000001
       x14 = 0x0000000000000063
       x15 = 0x0000000000000010
       x16 = 0x0000000000432280  
       x17 = 0x0000000040573554  libc.so.7`sigaction at sigaction.c:49
       x18 = 0x0000000000000000
       x19 = 0x662d3d5347414c46
       x20 = 0x58584300203d5347
       x21 = 0x414c46444c007365
       x22 = 0x67616b6361702f73
       x23 = 0x74726f702f727375
       x24 = 0x2f3d534547414b43
       x25 = 0x41500069763d524f
       x26 = 0x54494445003d4854
       x27 = 0x0000ffffffffc658
       x28 = 0x0000000000000000
        fp = 0x2d74656b63617262
        lr = 0x31353d6874706564
        sp = 0x0000ffffffffe600
        pc = 0x31353d6874706564
      cpsr = 0x20000000

Note the:

0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490

is somewhat before 0x0000ffffffffe600. It looks to be
a frame-pointer/lr-value pair. (And the 0x0000ffffffffc5c0
does point to a frame-pointer/lr-value pair that is
part of a coherent chain of them inside the stack region.)

It seems likely that despite the long distance
framepointer reference in the fp/lr value pair:

0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490

that sp = 0x0000ffffffffe600 was the result of an
increment by a small fixed amount from an sp near
0xffffffffe5a0, such as by code like the following
when forkshell tries to return:

sh`forkshell:
    0x40f520 <+1004>: ldp    x29, x30, [sp, #0x40]
    0x40f524 <+1008>: ldp    x20, x19, [sp, #0x30]
    0x40f528 <+1012>: ldp    x22, x21, [sp, #0x20]
    0x40f52c <+1016>: ldp    x24, x23, [sp, #0x10]
    0x40f530 <+1020>: ldp    x26, x25, [sp], #0x50
    0x40f534 <+1024>: ret    

So the prior is sp=0xffffffffe5b0 for the above code.
Also note that for SP=0xffffffffe5b0 initially that
code would fill in x19-x26 as they were actually
filled in: solid evidence of the sp that exit code
started with.

Note that forkshell had started with:

sh`forkshell:
    0x40f134 <+0>:  stp    x26, x25, [sp, #-0x50]!
    0x40f138 <+4>:  stp    x24, x23, [sp, #0x10]
    0x40f13c <+8>:  stp    x22, x21, [sp, #0x20]
    0x40f140 <+12>: stp    x20, x19, [sp, #0x30]
    0x40f144 <+16>: stp    x29, x30, [sp, #0x40]
    0x40f148 <+20>: add    x29, sp, #0x40            ; =0x40 

And that indicates that sp had a big change after:

    0x40f148 <+20>: add    x29, sp, #0x40            ; =0x40 

in order for x29=0x0000ffffffffc5c0 to have later
been written out as it was at 0xffffffffe5a0.

But by the freejob call (that is in forkshell's child
process path) that is indicated by the below the
sp had changed to be higher than the stack region:

0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490
(lldb) dis -s -4*4+0x000000000040f490
sh`forkshell:
    0x40f480 <+844>: ldrb   w8, [x20, #0x21]
    0x40f484 <+848>: cbz    w8, 0x40f490              ; <+860> at jobs.c:907
    0x40f488 <+852>: mov    x0, x20
    0x40f48c <+856>: bl     0x40e65c                  ; freejob at jobs.c:463
    0x40f490 <+860>: add    x20, x20, #0x30           ; =0x30 
. . .

where freejob started with:

(lldb) dis -s freejob
sh`freejob:
    0x40e65c <+0>:  str    x23, [sp, #-0x40]!
    0x40e660 <+4>:  stp    x22, x21, [sp, #0x10]
    0x40e664 <+8>:  stp    x20, x19, [sp, #0x20]
    0x40e668 <+12>: stp    x29, x30, [sp, #0x30]
    0x40e66c <+16>: add    x29, sp, #0x30            ; =0x30 
. . .

and the contained:

    0x40e668 <+12>: stp    x29, x30, [sp, #0x30]

wrote the frame-pointer/lr-value pair:

0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490

after freejob was called. freejob returns with:

(lldb) dis -s freejob -c 128
sh`freejob:
. . .
    0x40e748 <+236>: ldp    x29, x30, [sp, #0x30]
    0x40e74c <+240>: ldp    x20, x19, [sp, #0x20]
    0x40e750 <+244>: ldp    x22, x21, [sp, #0x10]
    0x40e754 <+248>: ldr    x23, [sp], #0x40
    0x40e758 <+252>: ret    
. . .

The lr-value from:

0xffffffffc5c0: 0x0000ffffffffc8f0 0x0000000000406648

refers to:

sh`evalcommand:
    0x406644 <+2012>: bl     0x40f134                  ; forkshell at jobs.c:838
    0x406648 <+2016>: cbz    w0, 0x40666c              ; <+2052> at eval.c:1175

as expected. This is in the stack region.

There is evidence of the following frame-pointer/lr-value
pair still in the stack-region from just before the fork but
while forkshell was active and before the big change in
sp value:

0xffffffffc570: 0x0000ffffffffc5c0 0x000000000040f1c8
sh`forkshell:
    0x40f1c4 <+144>: bl     0x413fc8                  ; flushall at output.c:236
    0x40f1c8 <+148>: bl     0x402920                  ; symbol stub for: fork

The parent process did not crash and so there is no evdence
that its sp value was ever wrong. So going into fork
things seem to have been okay.

So far it does not appear to me that there is information
left for inside or after the fork but before the freejob call
on the child process path. So the fork itself might have
returned with the wrong sp value or the problem might have
occurred a little later.

As far as the bad sp values in this example core file. . .

The content of what I've historically called "junk"
areas that are actually outside the stack region are
interesting:

. . .
0xffffffffe400: 0x6572662d6e776f6e 0x302e323164736265
0xffffffffe410: 0x56454c454b414d00 0x42494c00323d4c45
0xffffffffe420: 0x403d434e49464c45 0x6e69666c6562696c
0xffffffffe430: 0x4f465f444c004063 0x5445475241545f52
0xffffffffe440: 0x6f6c2f7273752f3d 0x637261612f6c6163
0xffffffffe450: 0x656e6f6e2d343668 0x6e69622f666c652d
0xffffffffe460: 0x3d62647000646c2f 0x2f62642f7261762f
0xffffffffe470: 0x74726f7000676b70 0x2f3d72696462645f
0xffffffffe480: 0x702f62642f726176 0x5f4d50007374726f
0xffffffffe490: 0x505f544e45524150 0x657665643d54524f
0xffffffffe4a0: 0x3668637261612f6c 0x652d656e6f6e2d34
0xffffffffe4b0: 0x43006363672d666c 0x5243530063633d43
0xffffffffe4c0: 0x6f6f722f3d545049 0x5f7374726f702f74
0xffffffffe4d0: 0x0000000000000078 0x637261612f737470 ("junk" (text) temporarily stops here)

In other words ('\0' terminated strings):

. . .
(lldb) print (char*)0xffffffffe400
(char *) $67 = 0x0000ffffffffe400 "nown-freebsd12.0"
(lldb) print (char*)0xffffffffe411
(char *) $66 = 0x0000ffffffffe411 "MAKELEVEL=2"
(lldb) print (char*)0xffffffffe433
(char *) $68 = 0x0000ffffffffe433 "LD_FOR_TARGET=/usr/local/aarch64-none-elf/bin/ld"
(lldb) print (char*)0xffffffffe464
(char *) $69 = 0x0000ffffffffe464 "pdb=/var/db/pkg"
(lldb) print (char*)0xffffffffe474
(char *) $71 = 0x0000ffffffffe474 "port_dbdir=/var/db/ports"
(lldb) print (char*)0xffffffffe48d
(char *) $60 = 0x0000ffffffffe48d "PM_PARENT_PORT=devel/aarch64-none-elf-gcc"
(lldb) print (char*)0xffffffffe4b7
(char *) $29 = 0x0000ffffffffe4b7 "CC=cc"
(lldb) print (char*)0xffffffffe4bd
(char *) $30 = 0x0000ffffffffe4bd "SCRIPT=/root/ports_x"

As for:

0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490 ("junk" (text) starts again after this line)
0xffffffffe5b0: 0x54494445003d4854 0x41500069763d524f x26, x25 values (see below)
0xffffffffe5c0: 0x2f3d534547414b43 0x74726f702f727375 x24, x23 values (see below)
0xffffffffe5d0: 0x67616b6361702f73 0x414c46444c007365 x22, x21 values (see below)
0xffffffffe5e0: 0x58584300203d5347 0x662d3d5347414c46 x20, x19 values (see below)
0xffffffffe5f0: 0x2d74656b63617262 0x31353d6874706564  fp,  lr values (see below); pc==lr as well.
0xffffffffe600: 0x346d673d344d0032 0x73752f3d564e4500
0xffffffffe610: 0x6d2f656d6f682f72 0x732e2f696d6b7261
0xffffffffe620: 0x2f3d647000637268 0x74726f702f727375
0xffffffffe630: 0x4441524750550073 0x703d4c4f4f545f45
0xffffffffe640: 0x657473616d74726f 0x5254524f46470072
0xffffffffe650: 0x4552534f003d4e41 0x4f00302e32313d4c
0xffffffffe660: 0x752f3d445750444c 0x702f6a626f2f7273
. . .

In other words:

(lldb) print (char*)0xffffffffe5b0
(char *) $72 = 0x0000ffffffffe5b0 "TH="
(The above is likely missing its beginning, having been replaced
 by the frame-popinter/lr-value pair.)
(lldb) print (char*)0xffffffffe5be
(char *) $73 = 0x0000ffffffffe5be "PACKAGES=/usr/ports/packages"
(lldb) print (char*)0xffffffffe5db
(char *) $74 = 0x0000ffffffffe5db "LDFLAGS= "
(lldb) print (char*)0xffffffffe5e5
(char *) $75 = 0x0000ffffffffe5e5 "CXXFLAGS=-fbracket-depth=512"
(lldb) print (char*)0xffffffffe602
(char *) $76 = 0x0000ffffffffe602 "M4=gm4"
(lldb) print (char*)0xffffffffe624
(char *) $77 = 0x0000ffffffffe624 "pd=/usr/ports"
(lldb) print (char*)0xffffffffe632
(char *) $79 = 0x0000ffffffffe632 "UPGRADE_TOOL=portmaster"
(lldb) print (char*)0xffffffffe64a
(char *) $81 = 0x0000ffffffffe64a "GFORTRAN="
(lldb) print (char*)0xffffffffe654
(char *) $82 = 0x0000ffffffffe654 "OSREL=12.0"
(lldb) print (char*)0xffffffffe65f
(char *) $83 = 0x0000ffffffffe65f "OLDPWD=/usr/obj/portswork/usr/ports/devel/aarch64-none-elf-gcc/work/.build"
. . .

So the middle range with the stack frames:

0xffffffffe4d0: 0x0000000000000078 0x637261612f737470 ("junk" (text) temporarily stops here)
0xffffffffe4e0: 0x00000000004345c8 0x0000000000434000
0xffffffffe4f0: 0x0000000000434000 0x0000000040a903e0
0xffffffffe500: 0x0000ffffffffe540 0x000000004054cd94
0xffffffffe510: 0x696d6b72616d2f6c 0x0000000000000000
0xffffffffe520: 0x0000000000000000 0x0000000000000000
0xffffffffe530: 0x0000000000000000 0xe8021690dc1f70b8
0xffffffffe540: 0x00000000004345c8 0x0000000000434000
0xffffffffe550: 0x0000000000434000 0x000000000000000f
0xffffffffe560: 0x0000ffffffffe5a0 0x000000000041aef0
0xffffffffe570: 0x0000000000434c38 0x732f7273752f3a6e
0xffffffffe580: 0x0000000000000001 0x0000000000000005
0xffffffffe590: 0x0000000040a33180 0x0000000000000000
0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490 ("junk" (text) starts again after this line)

has stomped on strings that are outside the stack
region. (The stack frames are the actual junk.)


===
Mark Millard
markmi at dsl-only.net

On 2017-Feb-7, at 2:44 AM, Mark Millard <markmi at dsl-only.net> wrote:

> Another core. The register read reported:
> 
>        fp = 0x0000000000000000
>        lr = 0x0000000000000000
>        sp = 0x0000fffffffee630
>        pc = 0x0000000000000000
> 
> And looking around (most nested to outer most):
> 
> 0xfffffffee530: 0x0000fffffffee570 0x000000004054cd94
> libc.so.7`__free:
>    0x4054cd90 <+144>: bl     0xad6fc                   ; ifree at jemalloc_jemalloc.c:1876
>    0x4054cd94 <+148>: adrp   x9, 185
> 0xfffffffee570: 0x0000fffffffee590 0x0000000000411300
> sh`ckfree:
>    0x4112fc <+28>: bl     0x4027e0                  ; symbol stub for: free
>    0x411300 <+32>: ldr    x8, [x19, #0x970]
> 0xfffffffee590: 0x0000fffffffee5d0 0x000000000040e6e8
> sh`freejob:
>    0x40e6e4 <+136>: bl     0x4112e0                  ; ckfree at memalloc.c:86
>    0x40e6e8 <+140>: adrp   x8, 38
> 0xfffffffee5d0: 0x0000ffffffffcaa0 0x000000000040f490
> sh`forkshell:
>    0x40f48c <+856>: bl     0x40e65c                  ; freejob at jobs.c:463
>    0x40f490 <+860>: add    x20, x20, #0x30           ; =0x30
> (Note that sp==0x0000fffffffee630 is fairly close to 0xfffffffee5d0.)
> 
> (sizable frame jump from 0xfffffffee5d0 to 0x0000ffffffffcaa0, size 0xE4D0==58576 bytes)
> (0xfffffffee5e0 up to 0xffffffffa890 (not inclusive) are all 0x0000000000000000)
> (The prior trace example did not have such a large area.)
> 
> 0xffffffffca50: 0x0000ffffffffcaa0 0x000000000040f1c8
> sh`forkshell:
>    0x40f1c4 <+144>: bl     0x413fc8                  ; flushall at output.c:236
>    0x40f1c8 <+148>: bl     0x402920                  ; symbol stub for: fork
>    0x40f1cc <+152>: mov    w19, w0
> (flushall a voids returning to 0x40f1c8 directly, instead making
> the last routine it calls return there instead of to flushall.)
> 
> 0xffffffffcaa0: 0x0000ffffffffcb50 0x0000000000405954
> sh`evaltree:
>    0x405950 <+1204>: bl     0x40f134                  ; forkshell at jobs.c:838
>    0x405954 <+1208>: cbnz   w0, 0x4059dc              ; <+1344> [inlined] evalpipe + 300 at eval.c:286
> 0xffffffffcb50: 0x0000ffffffffcde0 0x0000000000406e28
> sh`evalbackcmd:
>    0x406e24 <+336>: bl     0x40549c                  ; evaltree at eval.c:193
>    0x406e28 <+340>: ldur   w0, [x29, #-0x5c]
> 0xffffffffcde0: 0x0000ffffffffcf90 0x0000000000409324
> sh`argstr:
>    0x409320 <+428>: bl     0x406cd4                  ; evalbackcmd at eval.c:646
>    0x409324 <+432>: mov    x0, x26
> 0xffffffffcf90: 0x0000ffffffffcff0 0x0000000000408fa8
> sh`expandarg:
>    0x408fa4 <+108>: bl     0x409174                  ; argstr at expand.c:267
>    0x408fa8 <+112>: cbz    x19, 0x409020             ; <+232> at expand.c:236
> 0xffffffffcff0: 0x0000ffffffffd320 0x0000000000405f48
> sh`evalcommand:
>    0x405f44 <+220>: bl     0x408f38                  ; expandarg at expand.c:225
>    0x405f48 <+224>: ldr    x24, [x24, #0x8]
> 
> 0xffffffffd0f0: 0x0000ffffffffd320 0x00000000004068e4
> sh`evalcommand:
>    0x4068e0 <+2680>: bl     0x402be0                  ; symbol stub for: _setjmp
>    0x4068e4 <+2684>: cbz    w0, 0x406a04              ; <+2972> at eval.c:1101
> 
> 0xffffffffd320: 0x0000ffffffffd3d0 0x0000000000405570
> sh`evaltree:
>    0x40556c <+208>: bl     0x405e68                  ; evalcommand at eval.c:825
>    0x405570 <+212>: b      0x405a9c                  ; <+1536> at eval.c:623
>    0x405574 <+216>: ldr    x8, [x24, #0x8]
> 0xffffffffd3d0: 0x0000ffffffffd480 0x0000000000405550
> sh`cmdloop:
>    0x411030 <+248>: bl     0x40549c                  ; evaltree at eval.c:193
>    0x411034 <+252>: mov    w27, wzr
> 0xffffffffd480: 0x0000ffffffffd7b0 0x00000000004067d0
> sh`evalcommand:
>    0x4067cc <+2404>: bl     0x40549c                  ; evaltree at eval.c:193
>    0x4067d0 <+2408>: ldr    x8, [x24, #0x970]
> 0xffffffffd7b0: 0x0000ffffffffd860 0x0000000000405570
> sh`evaltree:
>    0x40556c <+208>: bl     0x405e68                  ; evalcommand at eval.c:825
>    0x405570 <+212>: b      0x405a9c                  ; <+1536> at eval.c:623
>    0x405574 <+216>: ldr    x8, [x24, #0x8]
> 0xffffffffd860: 0x0000ffffffffd910 0x0000000000405550
> sh`evaltree:
>    0x40554c <+176>: bl     0x40549c                  ; <+0> at eval.c:193
>    0x405550 <+180>: ldr    w8, [x22, #0x994]
> 0xffffffffd910: 0x0000ffffffffdc40 0x00000000004067d0
> sh`evalcommand:
>    0x4067cc <+2404>: bl     0x40549c                  ; evaltree at eval.c:193
>    0x4067d0 <+2408>: ldr    x8, [x24, #0x970]
> 
> 0xffffffffda10: 0x0000ffffffffdc40 0x000000000040673c
> sh`evalcommand:
>    0x406738 <+2256>: bl     0x402be0                  ; symbol stub for: _setjmp
>    0x40673c <+2260>: cbnz   w0, 0x406c60              ; <+3576> at eval.c:1042
> 
> 0xffffffffdc40: 0x0000ffffffffdcf0 0x0000000000405570
> sh`evaltree:
>    0x40556c <+208>: bl     0x405e68                  ; evalcommand at eval.c:825
>    0x405570 <+212>: b      0x405a9c                  ; <+1536> at eval.c:623
>    0x405574 <+216>: ldr    x8, [x24, #0x8]
> 0xffffffffdcf0: 0x0000ffffffffdd70 0x0000000000411034
> sh`cmdloop:
>    0x411030 <+248>: bl     0x40549c                  ; evaltree at eval.c:193
>    0x411034 <+252>: mov    w27, wzr
> 0xffffffffdd70: 0x0000ffffffffddd0 0x0000000000410ea8
> sh`main:
>    0x410ea4 <+656>: bl     0x410f38                  ; cmdloop at main.c:199
>    0x410ea8 <+660>: adrp   x8, 36
> 0xffffffffddd0: 0x0000ffffffffde10 0x0000000000402f30
> sh`__start:
>    0x402f2c <+356>: bl     0x410c14                  ; main at main.c:97
>    0x402f30 <+360>: bl     0x402ae0                  ; symbol stub for: exit
> 
> (_rtld is not in the core file)
> 0xffffffffde10: 0x0000000000000000 0x0000000040434658
> ld-elf.so.1`.rtld_start:
>    0x40434654 <+20>: bl     0x2e4c                    ; _rtld at rtld.c:339
>    0x40434658 <+24>: mov    x8, x0
> 
> So again the problem is associated with the forkshell/fork/freejob
> related materials.
> 
> (I mistakenly left out the evalcommand/_setjmp material
> when I made the trace in the below. The same for flushall.
> I've inserted some of that below, at least for
> the flushall context.)

On 2017-Feb-6, at 8:05 PM, Mark Millard <markmi at dsl-only.net> wrote:

> [I got a lucky sh core dump with more stack context/content
> available to look at for an example sh crash. This helps
> narrow things down.]
> 
> On 2017-Feb-5, at 1:12 AM, Mark Millard <markmi at dsl-only.net> wrote:
> 
>> [Top post of a new result.]
>> 
>> Using lldb to look at the memory for the stack around
>> sh failure points has some apparently fixed structure.
>> Example:
>> 
>> . . . junk values . . .
>> 0xffffffffe4d0: 0x0000000000000078 0x637261612f737470
>> 0xffffffffe4e0: 0x00000000004345c8 0x0000000000434000
>> 0xffffffffe4f0: 0x0000000000434000 0x0000000040a903e0
>> 0xffffffffe500: 0x0000ffffffffe540 0x000000004054cd94
>> 0xffffffffe510: 0x696d6b72616d2f6c 0x0000000000000000
>> 0xffffffffe520: 0x0000000000000000 0x0000000000000000
>> 0xffffffffe530: 0x0000000000000000 0xe8021690dc1f70b8
>> 0xffffffffe540: 0x00000000004345c8 0x0000000000434000
>> 0xffffffffe550: 0x0000000000434000 0x000000000000000f
>> 0xffffffffe560: 0x0000ffffffffe5a0 0x000000000041aef0
>> 0xffffffffe570: 0x0000000000434c38 0x732f7273752f3a6e
>> 0xffffffffe580: 0x0000000000000001 0x0000000000000005
>> 0xffffffffe590: 0x0000000040a33180 0x0000000000000000
>> 0xffffffffe5a0: 0x0000ffffffffc5c0 0x000000000040f490
>> . . .  junk values . . .
> 
> I got lucky and got a core dump that did not have the junk
> areas and could trace the stack's frame pointer chain
> between main and libc.so.7`__free (through freejob along
> the way). See later.
> 
>> where "register read" showed:
>> 
>>      sp = 0x0000ffffffffe600
>> 
>> (The distance and direction to the last non-junk line
>> from the reported sp in each example is the same.)
>> Looking around that 0x000000000040f490:
>> 
>>  0x40f48c: 0x97fffc74   bl     0x40e65c                  ; freejob at jobs.c:463
>>  0x40f490: 0x9100c294   add    x20, x20, #0x30           ; =0x30 
>> 
>> It is the same address and code in each case.
> 
> I should have originally noted that 0x40f48c is in
> forkshell, along the child process code-path:
> 
> pid_t
> forkshell(struct job *jp, union node *n, int mode)
> {
> . . . (see /usr/src/bin/sh/jobs.c for this) . . .
>       INTOFF;
>       if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0))
>               checkzombies();
>       flushall();
>       pid = fork();
>       if (pid == -1) {
>               TRACE(("Fork failed, errno=%d\n", errno));
>               INTON;
>               error("Cannot fork: %s", strerror(errno));
>       }
>       if (pid == 0) {
>               struct job *p;
>               int wasroot;
>               int i;
> 
>               TRACE(("Child shell %d\n", (int)getpid()));
>               wasroot = rootshell;
>               rootshell = 0;
>               handler = &main_handler;
>               closescript();
>               INTON;
>               forcelocal = 0;
>               clear_traps();
> #if JOBS
> . . . (see /usr/src/bin/sh/jobs.c for this) . . .
> #else
> . . . (see /usr/src/bin/sh/jobs.c for this) . . .
> #endif
>               INTOFF;
>               for (i = njobs, p = jobtab ; --i >= 0 ; p++)
>                       if (p->used)
>                               freejob(p);
>               INTON;
>               if (wasroot && iflag) {
>                       setsignal(SIGINT);
>                       setsignal(SIGQUIT);
>                       setsignal(SIGTERM);
>               }
>               return pid;
>       }
> . . . (see /usr/src/bin/sh/jobs.c for this) . . .
> 
>> Sometimes the junk values are all zeros over sizable
>> distances. Sometimes the sizable areas seem to have
>> random data.
>> 
>> /usr/src/bin/sh/jobs.c 's freejobs is:
>> 
>> static void
>> freejob(struct job *jp)
>> {
>>      struct procstat *ps;
>>      int i;
>> 
>>      INTOFF;
>>      if (bgjob == jp)
>>              bgjob = NULL;
>>      for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) {
>>              if (ps->cmd != nullstr)
>>                      ckfree(ps->cmd);
>>      }
>>      if (jp->ps != &jp->ps0)
>>              ckfree(jp->ps);
>>      jp->used = 0;
>> #if JOBS
>>      deljob(jp);
>> #endif
>>      INTON;
>> }
>> 
>> /usr/src/bin/sh/error.h defines INTOFF and INTON:
>> 
>> #define EXINT 0         /* SIGINT received */
>> #define EXERROR 1       /* a generic error */
>> #define EXEXEC 2        /* command execution failed */
>> #define EXEXIT 3        /* call exitshell(exitstatus) */
>> 
>> . . .
>> 
>> extern struct jmploc *handler;
>> extern volatile sig_atomic_t exception;
>> 
>> . . .
>> 
>> extern volatile sig_atomic_t suppressint;
>> extern volatile sig_atomic_t intpending;
>> 
>> #define INTOFF suppressint++
>> #define INTON { if (--suppressint == 0 && intpending) onint(); }
>> #define is_int_on() suppressint
>> #define SETINTON(s) suppressint = (s)
>> #define FORCEINTON {suppressint = 0; if (intpending) onint();}
>> #define SET_PENDING_INT intpending = 1
>> #define CLEAR_PENDING_INT intpending = 0
>> #define int_pending() intpending
>> 
>> void exraise(int) __dead2;
>> void onint(void) __dead2;
>> 
>> /usr/src/bin/sh/error.c hAS:
>> 
>> void
>> exraise(int e)
>> {
>>      INTOFF;
>>      if (handler == NULL)
>>              abort();
>>      exception = e;
>>      longjmp(handler->loc, 1);
>> }
>> . . .
>> void
>> onint(void)
>> {
>>      sigset_t sigs;
>> 
>>      intpending = 0;
>>      sigemptyset(&sigs);
>>      sigprocmask(SIG_SETMASK, &sigs, NULL);
>> 
>>      /*
>>       * This doesn't seem to be needed, since main() emits a newline.
>>       */
>> #if 0
>>      if (tcgetpgrp(0) == getpid())
>>              write(STDERR_FILENO, "\n", 1);
>> #endif
>>      if (rootshell && iflag)
>>              exraise(EXINT);
>>      else {
>>              signal(SIGINT, SIG_DFL);
>>              kill(getpid(), SIGINT);
>>              _exit(128 + SIGINT);
>>      }
>> }
>> 
>> # grep setjmp /usr/src/bin/sh/*
>> /usr/src/bin/sh/TOUR:so I implement it using setjmp and longjmp.  The global variable
>> /usr/src/bin/sh/error.h:#include <setjmp.h>
>> /usr/src/bin/sh/error.h: * BSD setjmp saves the signal mask, which violates ANSI C and takes time,
>> /usr/src/bin/sh/error.h: * so we use _setjmp instead.
>> /usr/src/bin/sh/error.h:#define setjmp(jmploc)	_setjmp(jmploc)
>> /usr/src/bin/sh/eval.c:	if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/eval.c:	if (setjmp(jmploc.loc))
>> /usr/src/bin/sh/eval.c:		if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/eval.c:		if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/eval.c:		if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/histedit.c:		if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/jobs.c:		if (setjmp(jmploc.loc))
>> /usr/src/bin/sh/main.c: * commands.  The setjmp call sets up the location to jump to when an
>> /usr/src/bin/sh/main.c:	if (setjmp(main_handler.loc)) {
>> /usr/src/bin/sh/parser.c:	if (setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/parser.c:	if (!setjmp(jmploc.loc)) {
>> /usr/src/bin/sh/trap.c:	if (!setjmp(loc1.loc)) {
>> /usr/src/bin/sh/trap.c:	if (!setjmp(loc2.loc)) {
>> /usr/src/bin/sh/var.c:	if (setjmp(jmploc.loc))
> 
> Here is the call chain that I was able to trace
> in the newer core dump:
> (most nested first to least nested last;
> showing frame pointer and lr value pairs
> and calls/return-places)
> 
> (ifree is not in the core file)
> 0xffffffffcc60: 0x0000ffffffffcca0 0x000000004054cd94
> libc.so.7`__free:
>   0x4054cd90 <+144>: bl     0xad6fc                   ; ifree at jemalloc_jemalloc.c:1876
>   0x4054cd94 <+148>: adrp   x9, 185
> 0xffffffffcca0: 0x0000ffffffffccc0 0x0000000000411300
> sh`ckfree:
>   0x4112fc <+28>: bl     0x4027e0                  ; symbol stub for: free
>   0x411300 <+32>: ldr    x8, [x19, #0x970]
> 0xffffffffccc0: 0x0000ffffffffcd00 0x000000000040e6e8
> sh`freejob:
>   0x40e6e4 <+136>: bl     0x4112e0                  ; ckfree at memalloc.c:86
>   0x40e6e8 <+140>: adrp   x8, 38
> 0xffffffffcd00: 0x0000ffffffffce20 0x000000000040f490
> sh`forkshell:
>   0x40f48c <+856>: bl     0x40e65c                  ; freejob at jobs.c:463
>   0x40f490 <+860>: add    x20, x20, #0x30           ; =0x30 

0xffffffffcdd0: 0x0000ffffffffce20 0x000000000040f1c8
sh`forkshell:
   0x40f1c4 <+144>: bl     0x413fc8                  ; flushall at output.c:236
   0x40f1c8 <+148>: bl     0x402920                  ; symbol stub for: fork
   0x40f1cc <+152>: mov    w19, w0
(flushall a voids returning to 0x40f1c8 directly, instead making
the last routine it calls return there instead of to flushall.)

> 0xffffffffce20: 0x0000ffffffffced0 0x0000000000405954
> sh`evaltree:
>   0x405950 <+1204>: bl     0x40f134                  ; forkshell at jobs.c:838
>   0x405954 <+1208>: cbnz   w0, 0x4059dc              ; <+1344> [inlined] evalpipe + 300 at eval.c:286
> 0xffffffffced0: 0x0000ffffffffd160 0x0000000000406e28
> sh`evalbackcmd:
>   0x406e24 <+336>: bl     0x40549c                  ; evaltree at eval.c:193
>   0x406e28 <+340>: ldur   w0, [x29, #-0x5c]0xffffffffcd60: 0x0000ffffffffcf90 0x00000000004068e4

> 0xffffffffd160: 0x0000ffffffffd310 0x0000000000409324
> sh`argstr:
>   0x409320 <+428>: bl     0x406cd4                  ; evalbackcmd at eval.c:646
>   0x409324 <+432>: mov    x0, x26
> 0xffffffffd310: 0x0000ffffffffd370 0x0000000000408fa8
> sh`expandarg:
>   0x408fa4 <+108>: bl     0x409174                  ; argstr at expand.c:267
>   0x408fa8 <+112>: cbz    x19, 0x409020             ; <+232> at expand.c:236
> 0xffffffffd370: 0x0000ffffffffd5f0 0x0000000000407530
> sh`exphere:
>   0x40752c <+212>: bl     0x408f38                  ; expandarg at expand.c:225
>   0x407530 <+216>: ldr    x8, [x20]
> 0xffffffffd5f0: 0x0000ffffffffd630 0x00000000004073f0
> sh`expredir:
>   0x4073ec <+112>: bl     0x407458                  ; exphere at eval.c:494
>   0x4073f0 <+116>: b      0x407428                  ; <+172> at eval.c:535
> 0xffffffffd630: 0x0000ffffffffd960 0x0000000000406154
> sh`evalcommand:
>   0x406150 <+744>: bl     0x40737c                  ; expredir at eval.c:532
>   0x406154 <+748>: ldur   w27, [x29, #-0x68]
> 0xffffffffd960: 0x0000ffffffffda10 0x0000000000405570
> sh`evaltree:
>   0x40556c <+208>: bl     0x405e68                  ; evalcommand at eval.c:825
>   0x405570 <+212>: b      0x405a9c                  ; <+1536> at eval.c:623
>   0x405574 <+216>: ldr    x8, [x24, #0x8]
> 0xffffffffda10: 0x0000ffffffffdac0 0x00000000004056b4
> sh`evaltree:
>   0x4056b0 <+532>: bl     0x40549c                  ; <+0> at eval.c:193
>   0x4056b4 <+536>: ldr    w8, [x19, #0x990]
> 0xffffffffdac0: 0x0000ffffffffdb70 0x0000000000405550
> sh`evaltree:
>   0x40554c <+176>: bl     0x40549c                  ; <+0> at eval.c:193
>   0x405550 <+180>: ldr    w8, [x22, #0x994]
> 0xffffffffdb70: 0x0000ffffffffdbf0 0x0000000000411034
> sh`cmdloop:
>   0x411030 <+248>: bl     0x40549c                  ; evaltree at eval.c:193
>   0x411034 <+252>: mov    w27, wzr
> 0xffffffffdbf0: 0x0000ffffffffdc50 0x0000000000410ea8
> sh`main:
>   0x410ea4 <+656>: bl     0x410f38                  ; cmdloop at main.c:199
>   0x410ea8 <+660>: adrp   x8, 36
> 0xffffffffdc50: 0x0000ffffffffdc90 0x0000000000402f30
> sh`__start:
>   0x402f2c <+356>: bl     0x410c14                  ; main at main.c:97
>   0x402f30 <+360>: bl     0x402ae0                  ; symbol stub for: exit
> 
> (_rtld is not in the core file)
> 0xffffffffdc90: 0x0000000000000000 0x0000000040434658
> ld-elf.so.1`.rtld_start:
>   0x40434654 <+20>: bl     0x2e4c                    ; _rtld at rtld.c:339
>   0x40434658 <+24>: mov    x8, x0
> 
> Some of the most nested possibly had returned. But the
> forkshell / freejob general time frame seem to match
> everything that I've seen.
> 
> [The details of the middle "eval*" related layers vary
> from what I can tell.]
> 
> "register read" shows fp, lr, and pc majorly
> messed up.
> 
> General Purpose Registers:
>       x0 = 0x0000000000000000
>       x1 = 0x00000000404346e8  ld-elf.so.1`_rtld_tlsdesc
>       x2 = 0x0000000040a00000
>       x3 = 0x0000000000000002
>       x4 = 0x0000000000000096
>       x5 = 0x0000000040a5fd10
>       x6 = 0x0000000000434c28  sh..bss + 9448
>       x7 = 0x0000000000434c28  sh..bss + 9448
>       x8 = 0x0000000000000001
>       x9 = 0x0000000000000000
>      x10 = 0x0000000000000000
>      x11 = 0x0000000040a350c0
>      x12 = 0x0000000040a0e770
>      x13 = 0x0000000000000072
>      x14 = 0x000000000000006f
>      x15 = 0x0000000000000010
>      x16 = 0x0000000000432340  
>      x17 = 0x000000004054cd00  libc.so.7`__free at jemalloc_jemalloc.c:2007
>      x18 = 0x0000000000000000
>      x19 = 0x0000000000000000
>      x20 = 0x0000000000000000
>      x21 = 0x0000000000000001
>      x22 = 0x0000000040a5ff10
>      x23 = 0x0000ffffffffd190
>      x24 = 0x0000000000434000  sh..bss + 6336
>      x25 = 0x0000000000434000  sh..bss + 6336
>      x26 = 0x0000ffffffffcd00
>      x27 = 0x0000000000434000  sh..bss + 6336
>      x28 = 0x0000000040a6f5e0
>       fp = 0x0000000040a5fed8
>       lr = 0x0000000000000000
>       sp = 0x0000ffffffffcd60
>       pc = 0x0000000000000000
>     cpsr = 0x60000000
> 
> sp is also odd by being in the middle of the stack range
> for:
> 
> 0xffffffffcd00: 0x0000ffffffffce20 0x000000000040f490
> sh`forkshell:
>   0x40f48c <+856>: bl     0x40e65c                  ; freejob at jobs.c:463
>   0x40f490 <+860>: add    x20, x20, #0x30           ; =0x30 
> 0xffffffffce20: 0x0000ffffffffced0 0x0000000000405954
> sh`evaltree:
>   0x405950 <+1204>: bl     0x40f134                  ; forkshell at jobs.c:838
>   0x405954 <+1208>: cbnz   w0, 0x4059dc              ; <+1344> [inlined] evalpipe + 300 at eval.c:286
> 
> NOTE: The fork happened earlier in sh`forkshell and this
> is the child process that has the odd value.
> 
> [It leaves me wondering if 0x0000ffffffffcd60 is a stack
> pointer value associated with a call to something
> earlier than the sh`forkshell call that is called by
> sh`forkshell .]
> 
> Also: in the ones with only a small section of the junk
> areas the equivalent of:
> 
> 0xffffffffcd00: 0x0000ffffffffce20 0x000000000040f490
> 
> is the largest addressed non-junk content in the area
> and the equivalent of:
> 
> 0xffffffffce20: 0x0000ffffffffced0 0x0000000000405954
> 
> would instead show zeros or "random" garbage values.
> 
> In this case, however that range of the stack looks like:
> 
> . . .
> 0xffffffffcd00: 0x0000ffffffffce20 0x000000000040f490
> 0xffffffffcd10: 0x0000ffffffffcd00 0x0000000000434000
> 0xffffffffcd20: 0x0000000000434000 0x0000ffffffffd190
> 0xffffffffcd30: 0x0000000040a5ff10 0x0000000000000001
> 0xffffffffcd40: 0x0000000000000000 0x0000000000000000
> 0xffffffffcd50: 0x0000000040a5fed8 0x0000000000000000
> 0xffffffffcd60: 0x0000ffffffffcf90 0x00000000004068e4
> 0xffffffffcd70: 0x0000000000000000 0x827a80ccb3228215
> 0xffffffffcd80: 0x0000000040a6f5c0 0x0000000000434000
> 0xffffffffcd90: 0x0000000000434000 0x0000000000434000
> 0xffffffffcda0: 0x0000000000434000 0x0000000000434000
> 0xffffffffcdb0: 0x0000000040a6f638 0x0000000000000000
> 0xffffffffcdc0: 0x0000000040a350c0 0x0000000000434000
> 0xffffffffcdd0: 0x0000ffffffffce20 0x000000000040f1c8
> 0xffffffffcde0: 0x0000000000000003 0x0000000040a350c0
> 0xffffffffcdf0: 0x0000000040a6f5c0 0x0000000000434000
> 0xffffffffce00: 0x0000000000434000 0x0000000040a6f638
> 0xffffffffce10: 0x0000000000000000 0x0000000000434000
> 0xffffffffce20: 0x0000ffffffffced0 0x0000000000405954
> . . .
> 
> Interestingly 0xffffffffcd60 reported for the sp looks
> like it has a frame-pointer/lr-value pair that does not
> fit with the overall call chain that ties together but
> is some fragment of a prior(?) call chain:
> 
> 0xffffffffcd60: 0x0000ffffffffcf90 0x00000000004068e4
> sh`evalcommand:
>   0x4068e0 <+2680>: bl     0x402be0                  ; symbol stub for: _setjmp
>   0x4068e4 <+2684>: cbz    w0, 0x406a04              ; <+2972> at eval.c:1101
> 
> It looks like it is a record from calling _setjmp in
> sh`evalcommand .
> 
> (sh uses _setjmp/_longjmp via macros that turn
> into them for setjmp/longjmp references in
> sh's source code.)
> 
> Interestingly (likely junk relative to the above):
> 
> 0xffffffffcf90: 0x0000000000000000 0x0000000000432000
> 
> where:
> 
> (lldb) dis -s 0x0000000000432000
> sh`__frame_dummy_init_array_entry:
>   0x432000 <+0>: .long  0x00402fac                ; unknown opcode
>   0x432004 <+4>: .long  0x00000000                ; unknown opcode
> (lldb) dis -s __frame_dummy_init_array_entry -c32
> sh`frame_dummy:
>   0x402fac <+0>:  adrp   x8, 48
>   0x402fb0 <+4>:  adrp   x1, 48
>   0x402fb4 <+8>:  ldr    x8, [x8, #0x30]
>   0x402fb8 <+12>: ldr    x1, [x1, #0x228]
>   0x402fbc <+16>: cmp    x8, #0x0                  ; =0x0 
>   0x402fc0 <+20>: ccmp   x1, #0x0, #0x4, ne
>   0x402fc4 <+24>: b.ne   0x402fcc                  ; <+32>
>   0x402fc8 <+28>: ret    
>   0x402fcc <+32>: adrp   x0, 48
>   0x402fd0 <+36>: add    x0, x0, #0x30             ; =0x30 
>   0x402fd4 <+40>: br     x1
> 
> sh`lookupalias:
> . . .
> 
> 
> Ohter notes:
> 
> Some examples of funcnest==0 others have (e.g.) funcnest==2.
> This one had funcnest==0.
> 
> commandname varies. In this case it was:
> 
> (lldb) print commandname
> (char *) $74 = 0x0000ffffffffe210 "/usr/obj/portswork/usr/ports/devel/aarch64-none-elf-gcc/work/gcc-6.3.0/libiberty/configure"
> 
> Other examples include:
> 
> (lldb) print commandname
> (char *) $0 = 0x0000ffffffffdc40 "/usr/obj/portswork/usr/ports/devel/aarch64-none-elf-gcc/work/gcc-6.3.0/fixincludes/configure"
> 
> (lldb) print commandname
> (char *) $0 = 0x0000ffffffffe498 "/usr/obj/portswork/usr/ports/devel/aarch64-none-elf-gcc/work/gcc-6.3.0/libiberty/../config.sub"
> 
> (lldb) print commandname
> (char *) $0 = 0x0000ffffffffe398 "../libtool"
> 
> 
> So far the forkshell/fork/freejob and associated materials always seeming
> to be involved is all that I've found that is common (at least that is
> suggested by what I see so far) within the sh context.
> 
>> Other notes:
>> 
>> As a personal investigation I've temporarily changed to using
>> something not fully generic but based on gic-400 specifics:
>> 
>> # svnlite diff /usr/src/sys/arm/arm/gic.c
>> Index: /usr/src/sys/arm/arm/gic.c
>> ===================================================================
>> --- /usr/src/sys/arm/arm/gic.c  (revision 312982)
>> +++ /usr/src/sys/arm/arm/gic.c  (working copy)
>> @@ -672,9 +672,13 @@
>> 
>>      if (irq >= sc->nirqs) {
>> #ifdef GIC_DEBUG_SPURIOUS
>> +#define EXPECTED_SPURIOUS_IRQ 1023
>> +           if (irq != EXPECTED_SPURIOUS_IRQ) {
>>              device_printf(sc->gic_dev,
>> -                   "Spurious interrupt detected: last irq: %d on CPU%d\n",
>> +                   "Spurious interrupt %d detected of %d: last irq: %d on CPU%d\n",
>> +                   irq, sc->nirqs,
>>                  sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid));
>> +            }
>> #endif
>>              return (FILTER_HANDLED);
>>      }
>> @@ -720,6 +724,16 @@
>>      if (irq < sc->nirqs)
>>              goto dispatch_irq;
>> 
>> +       if (irq != EXPECTED_SPURIOUS_IRQ) {
>> +#undef EXPECTED_SPURIOUS_IRQ
>> +#ifdef GIC_DEBUG_SPURIOUS
>> +               device_printf(sc->gic_dev,
>> +                   "Spurious end interrupt %d detected of %d: last irq: %d on CPU%d\n",
>> +                   irq, sc->nirqs,
>> +                   sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid));
>> +#endif
>> +       }
>> +
>>      return (FILTER_HANDLED);
>> }
>> 
>> 
>> The result was no notices of Spurious interrupts have been generated:
>> All of the odd interrupts were the special 1023 value.
>> 
>> [As far as I could tell from the code the configuration is such that
>> 1022 should not be generated --and were not. 1020 and 1021 are
>> reserved and should not be generated.]



===
Mark Millard
markmi at dsl-only.net

_______________________________________________
freebsd-arm at freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-arm
To unsubscribe, send any mail to "freebsd-arm-unsubscribe at freebsd.org"



More information about the freebsd-arm mailing list