Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

runtime: "fatal error: unknown caller pc" crash on darwin/arm #16760

Closed
dcu opened this issue Aug 17, 2016 · 35 comments
Closed

runtime: "fatal error: unknown caller pc" crash on darwin/arm #16760

dcu opened this issue Aug 17, 2016 · 35 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@dcu
Copy link

dcu commented Aug 17, 2016

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
$ go version
go version go1.7 darwin/amd64

and

$ gomobile version
gomobile version +0ba4e64 Tue Aug 16 10:53:25 2016 +0000 (android,ios); androidSDK=/usr/local/opt/android-sdk/platforms/android-22
  1. What operating system and processor architecture are you using (go env)?
    darwin/arm(64)
  2. What did you do?
    I'm not sure how to reproduce this, it's more likely to happen after sending the app to background and waiting few minutes and then resume it.
    I don't have code to provide at the moment but I got a backtrace:
runtime: unexpected return pc for runtime.cgocallback_gofunc called from 0x0
fatal error: unknown caller pc
runtime stack:
runtime.throw(0x5bca2e, 0x11)
/opt/go/src/runtime/panic.go:566 +0x80
runtime.gentraceback(0x2eaf9c, 0x503db8e8, 0x0, 0x503983c0, 0x0, 0x0, 0x7fffffff, 0x70726efc, 0x0, 0x0, ...)
/opt/go/src/runtime/traceback.go:317 +0x1620
runtime.scanstack(0x503983c0, 0x503bb32c)
/opt/go/src/runtime/mgcmark.go:770 +0x344
runtime.scang(0x503983c0, 0x503bb32c)
/opt/go/src/runtime/proc.go:830 +0xb0
runtime.markroot.func1()
/opt/go/src/runtime/mgcmark.go:234 +0xac
runtime.systemstack(0x503ba000)
/opt/go/src/runtime/asm_arm.s:247 +0x8c
runtime.mstart()
/opt/go/src/runtime/proc.go:1081
goroutine 29 [running]:
runtime.systemstack_switch()
/opt/go/src/runtime/asm_arm.s:192 +0x4 fp=0x50492f24 sp=0x50492f20
runtime.markroot(0x503bb32c, 0x7)
/opt/go/src/runtime/mgcmark.go:239 +0x34c fp=0x50492f60 sp=0x50492f24
runtime.gcDrain(0x503bb32c, 0x5)
/opt/go/src/runtime/mgcmark.go:956 +0x394 fp=0x50492f90 sp=0x50492f60
runtime.gcBgMarkWorker(0x503baa00)
/opt/go/src/runtime/mgc.go:1453 +0x66c fp=0x50492fcc sp=0x50492f90
runtime.goexit()
/opt/go/src/runtime/asm_arm.s:998 +0x4 fp=0x50492fcc sp=0x50492fcc
created by runtime.gcBgMarkStartWorkers
/opt/go/src/runtime/mgc.go:1342 +0x8c
goroutine 17 [GC assist wait (scan), locked to thread]:
oursdk/vendor/github.com/boltdb/bolt.(*meta).sum64(0x50830580, 0x4b3141ff, 0x0)
oursdk/vendor/github.com/boltdb/bolt/db.go:968 +0x34
oursdk/vendor/github.com/boltdb/bolt.(*meta).write(0x50830580, 0x5083e000)
oursdk/vendor/github.com/boltdb/bolt/db.go:961 +0x340
oursdk/vendor/github.com/boltdb/bolt.(*Tx).writeMeta(0x507eb400, 0x0, 0x0)
oursdk/vendor/github.com/boltdb/bolt/tx.go:499 +0x108
oursdk/vendor/github.com/boltdb/bolt.(*Tx).Commit(0x507eb400, 0x0, 0x0)
oursdk/vendor/github.com/boltdb/bolt/tx.go:211 +0x638
oursdk/vendor/github.com/boltdb/bolt.(*DB).Update(0x5080afc0, 0x503dbbe0, 0x0, 0x0)
oursdk/vendor/github.com/boltdb/bolt/db.go:575 +0x114
oursdk/storage.(*BoltDB).createBucket(0x50413a40, 0x5080afc0, 0x5bb02c, 0xc, 0x0, 0x0)
oursdk/storage/boltdb.go:248 +0x60
oursdk/storage.(*BoltDB).open(0x50413a40, 0x5bb02c, 0xc, 0x1, 0x1, 0x0, 0x0)
oursdk/storage/boltdb.go:233 +0x28c
oursdk/storage.(*BoltDB).AllKeys(0x50413a40, 0x5bb02c, 0xc, 0x0, 0x0, 0x0, 0x0)
oursdk/storage/boltdb.go:174 +0x64
oursdk/coresdk.GetTokensIdsStr(0x0, 0x0)
oursdk/token.go:174 +0x58
oursdk/coresdk.getTokenIds(0x0, 0x0, 0x0)
oursdk/token.go:183 +0x24
oursdk/coresdk.fetchTokens(0x50769ac0, 0x0, 0x0, 0x0)
oursdk/token.go:192 +0x58
oursdk/coresdk.(*Device).SyncTokens(0x50769ac0, 0x0, 0x0)
oursdk/device.go:300 +0x34
oursdk/coresdk.(*Device).Sync(0x50769ac0, 0x0, 0x0)
oursdk/device.go:197 +0x150
/var/folders/y/ws09jpg90_b5y710wmd7kvj5sbl416/T/gomobile-work-594142717/src/gomobile_bind.proxycoresdk_Device_Sync(0xffffffd6, 0x0, 0x0)
/var/folders/y_/ws09jpg90_b5y710wmd7kvj5sbl416/T/gomobile-work-594142717/src/gomobile_bind/go_coresdkmain.go:609 +0x5c
/var/folders/y/ws09jpg90_b5y710wmd7kvj5sbl416/T/gomobile-work-594142717/src/gomobile_bind._cgoexpwrap_7047d42d6f98_proxycoresdk_Device_Sync(0xffffffd6, 0x0, 0x0)
??:0 +0x68
goroutine 34 [syscall, locked to thread]:
runtime.goexit()
/opt/go/src/runtime/asm_arm.s:998 +0x4
goroutine 23 [IO wait]:
net.runtime_pollWait(0x480ff78, 0x72, 0x50485000)
/opt/go/src/runtime/netpoll.go:160 +0x60
net.(*pollDesc).wait(0x503fe3b8, 0x72, 0x0, 0x0)
/opt/go/src/net/fd_poll_runtime.go:73 +0x34
net.(*pollDesc).waitRead(0x503fe3b8, 0x0, 0x0)
/opt/go/src/net/fd_poll_runtime.go:78 +0x30
net.(*netFD).Read(0x503fe380, 0x50485000, 0x1000, 0x1000, 0x0, 0x705248, 0x50416000)
/opt/go/src/net/fd_unix.go:220 +0x1f8
net.(*conn).Read(0x50418d90, 0x50485000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/opt/go/src/net/net.go:173 +0xbc
crypto/tls.(*block).readFromUntil(0x5047e7a0, 0x2c48050, 0x50418d90, 0x5, 0x0, 0x0)
/opt/go/src/crypto/tls/conn.go:469 +0xc8
crypto/tls.(*Conn).readRecord(0x5048a000, 0x62da17, 0x0, 0x0)
/opt/go/src/crypto/tls/conn.go:571 +0x228
crypto/tls.(*Conn).Read(0x5048a000, 0x50695000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
/opt/go/src/crypto/tls/conn.go:1072 +0x148
net/http.(*persistConn).Read(0x50488000, 0x50695000, 0x1000, 0x1000, 0x503d7da4, 0x0, 0x0)
/opt/go/src/net/http/transport.go:1200 +0x1d0
bufio.(*Reader).fill(0x506ca900)
/opt/go/src/bufio/bufio.go:97 +0x1cc
bufio.(*Reader).Peek(0x506ca900, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
/opt/go/src/bufio/bufio.go:129 +0xb4
net/http.(*persistConn).readLoop(0x50488000)
/opt/go/src/net/http/transport.go:1350 +0x1d0
created by net/http.(*Transport).dialConn
/opt/go/src/net/http/transport.go:1001 +0xdd0
goroutine 24 [select]:
net/http.(*persistConn).writeLoop(0x50488000)
/opt/go/src/net/http/transport.go:1578 +0x2f0
created by net/http.(*Transport).dialConn
/opt/go/src/net/http/transport.go:1002 +0xdf0
  1. What did you expect to see?
    iOS app not crashing when resuming it
  2. What did you see instead?
    The application crashes randomly and it is hard to reproduce. It seems to be more frequent on armv7 than arm64
@rasky
Copy link
Member

rasky commented Aug 17, 2016

/cc @aclements @minux @crawshaw (as requested)

@aclements
Copy link
Member

/cc @ianlancetaylor

This may look like a GC problem, but the GC's just tripping over a bad call stack surrounding a cgo call.

@dcu, it looks like the traceback got cut off. I would expect at least one more line. Is that the whole traceback? What version of github.com/boltdb/bolt do you have vendored? At master, db.go:968 is a blank line between functions, and bolt.(*meta).sum64 doesn't go anywhere near cgo code.

@dcu
Copy link
Author

dcu commented Aug 17, 2016

@aclements thanks, I updated the description including the whole stack trace. I'm using the master (94c8db596809690a3f7046fa83c7b0dda13a3222)

@aclements
Copy link
Member

Thanks!

I bet this is happening at the bottom of goroutine 17's stack where gomobile bind's wrapper did a cgo callback into coresdk.(*Device).Sync.

@dcu
Copy link
Author

dcu commented Aug 17, 2016

I'm trying to find the correct boltdb version we were using at that point since looks like we updated it recently. I'll report back soon.

@dcu
Copy link
Author

dcu commented Aug 17, 2016

This is the boltdb version we were using when we captured that trace:

https://github.com/boltdb/bolt/tree/b514920f8f2e0a68f857e5a12c774f385a59aef9

@dcu
Copy link
Author

dcu commented Aug 17, 2016

#16772 is related with boltdb but I'm not sure if it's related to this one

@dcu
Copy link
Author

dcu commented Aug 19, 2016

We updated BoltDB to the latest one and we are still seeing the crash randomly. Unfortunately we weren't using the SDK in debug mode so we couldn't get the stack trace. I'll update again if we get the trace.

@eliasnaur
Copy link
Contributor

@dcu is this a regression from Go 1.6? If so, we should consider applying its eventual fix to a 1.7 point release.

@aclements
Copy link
Member

@dcu, can you say more about the call from Java code to coresdk.(*Device).Sync? In particular, do you know if the thread that made the call was started in Java/native code, or did a goroutine call into Java/native code and then that called back into Go code?

runtime.cgocallback_gofunc does some very subtle things involving stack switches and overlapping stack frames. It's possible we're getting that wrong in some cases on darwin/arm(64).

@dcu
Copy link
Author

dcu commented Aug 23, 2016

@eliasnaur I think it's a regression but I'm not sure because our project doesn't work on 1.6 because of #12896

@aclements yeah, Device.Sync is called from a GCD thread. goroutines don't interact with objective-c in this code.
Also, we haven't seen this issue happening on Android

@quentinmit quentinmit added this to the Go1.8 milestone Sep 6, 2016
@quentinmit
Copy link
Contributor

I'm going to mark this Go1.8 but if we find a fix that is deemed safe we can backport it to Go1.7.x

@aclements
Copy link
Member

@dcu, if I were to send you a runtime patch to report more debug info, would it be possible for you to run with it?

@aclements yeah, Device.Sync is called from a GCD thread. goroutines don't interact with objective-c in this code.

(Sorry, not sure why I said Java in my earlier reply. Must have been thinking Android.) I'm only familiar with GCD at a very high level. Could you give me a sense of how you're wiring up GCD and Go? A snippet of code would be great. I'm wondering if there's some particular bad interaction between GCD and Go.

@dcu
Copy link
Author

dcu commented Sep 6, 2016

@aclements yeah sure, I'd more than happy to test.
Calling go from GCD is very easy, it's something like this:

let queue = dispatch_queue_create("sync", nil)
dispatch_async(queue) {
    self.gosdk!.sync()
}

we also tested #16644 and it still crashes in our app but it doesn't in a simpler app. not sure why.

@dcu
Copy link
Author

dcu commented Sep 22, 2016

@aclements I'm getting very frequent crash when the app is in background, sadly I can't see the backtrace because it doesn't really crash on XCode. I changed the page size in the compiler and it seems the crash is less frequent. Any idea how can I help debug this issue?

@dcu
Copy link
Author

dcu commented Sep 23, 2016

continuing with the investigation I found out that if I remove a goroutine that's always running the app doesn't crash. The crash doesn't happen on Android even with the goroutine.

@dcu
Copy link
Author

dcu commented Sep 28, 2016

@aclements does this tell you anything:

runtime.kevent:
    0x8d7740 <+0>:  ldr    r12, [pc, #0x28]          ; <+48>
    0x8d7744 <+4>:  ldr    r0, [sp, #0x4]
    0x8d7748 <+8>:  ldr    r1, [sp, #0x8]
    0x8d774c <+12>: ldr    r2, [sp, #0xc]
    0x8d7750 <+16>: ldr    r3, [sp, #0x10]
    0x8d7754 <+20>: ldr    r4, [sp, #0x14]
    0x8d7758 <+24>: ldr    r5, [sp, #0x18]
    0x8d775c <+28>: svc    #0x80
->  0x8d7760 <+32>: rsbhs  r0, r0, #0
    0x8d7764 <+36>: str    r0, [sp, #0x1c]
    0x8d7768 <+40>: add    pc, lr, #0
    0x8d776c <+44>: b      0x8d776c                  ; <+44>
    0x8d7770 <+48>: andeq  r0, r0, r11, ror #2
runtime.netpoll:
    0x89fa78 <+0>:   ldr    r1, [r10, #0x8]
    0x89fa7c <+4>:   ldr    r11, [pc, #0x264]         ; <+624>
    0x89fa80 <+8>:   add    r2, sp, r11
    0x89fa84 <+12>:  cmp    r2, r1
    0x89fa88 <+16>:  bls    0x89fcd8                  ; <+608>
    0x89fa8c <+20>:  str    lr, [sp, #-0x53c]!
    0x89fa90 <+24>:  mov    r0, #0
    0x89fa94 <+28>:  ldr    r11, [pc, #0x250]         ; <+628>
    0x89fa98 <+32>:  add    r11, pc, r11
    0x89fa9c <+36>:  ldr    r0, [r11]
    0x89faa0 <+40>:  mvn    r11, #0
    0x89faa4 <+44>:  cmp    r0, r11
    0x89faa8 <+48>:  bne    0x89fab8                  ; <+64>
    0x89faac <+52>:  mov    r0, #0
    0x89fab0 <+56>:  str    r0, [sp, #0x544]
    0x89fab4 <+60>:  ldr    pc, [sp], #1340
    0x89fab8 <+64>:  mov    r0, #0
    0x89fabc <+68>:  str    r0, [sp, #0x38]
    0x89fac0 <+72>:  mov    r0, #0
    0x89fac4 <+76>:  str    r0, [sp, #0x30]
    0x89fac8 <+80>:  str    r0, [sp, #0x34]
    0x89facc <+84>:  ldrb   r0, [sp, #0x540]
    0x89fad0 <+88>:  cmp    r0, #0
    0x89fad4 <+92>:  bne    0x89fae0                  ; <+104>
    0x89fad8 <+96>:  add    r0, sp, #48
    0x89fadc <+100>: str    r0, [sp, #0x38]
    0x89fae0 <+104>: add    r1, sp, #60
    0x89fae4 <+108>: mov    r0, #0
    0x89fae8 <+112>: add    r2, r1, #1280
    0x89faec <+116>: str    r0, [r1], #4
    0x89faf0 <+120>: cmp    r2, r1
    0x89faf4 <+124>: bne    0x89faec                  ; <+116>
    0x89faf8 <+128>: ldr    r11, [pc, #0x1f0]         ; <+632>
    0x89fafc <+132>: add    r11, pc, r11
    0x89fb00 <+136>: ldr    r0, [r11]
    0x89fb04 <+140>: str    r0, [sp, #0x4]
    0x89fb08 <+144>: mov    r0, #0
    0x89fb0c <+148>: str    r0, [sp, #0x8]
    0x89fb10 <+152>: mov    r0, #0
    0x89fb14 <+156>: str    r0, [sp, #0xc]
    0x89fb18 <+160>: add    r0, sp, #60
    0x89fb1c <+164>: add    r0, r0, #0
    0x89fb20 <+168>: str    r0, [sp, #0x10]
    0x89fb24 <+172>: mov    r0, #64
    0x89fb28 <+176>: str    r0, [sp, #0x14]
    0x89fb2c <+180>: ldr    r0, [sp, #0x38]
    0x89fb30 <+184>: str    r0, [sp, #0x18]
    0x89fb34 <+188>: bl     0x8d7740                  ; runtime.kevent
    0x89fb38 <+192>: ldr    r5, [sp, #0x1c]
    0x89fb3c <+196>: cmp    r5, #0
    0x89fb40 <+200>: bge    0x89fbfc                  ; <+388>
    0x89fb44 <+204>: mvn    r11, #3
    0x89fb48 <+208>: cmp    r5, r11
    0x89fb4c <+212>: beq    0x89faf8                  ; <+128>
    0x89fb50 <+216>: rsb    r0, r5, #0
    0x89fb54 <+220>: str    r0, [sp, #0x2c]
    0x89fb58 <+224>: bl     0x8a3de8                  ; runtime.printlock
    0x89fb5c <+228>: ldr    r0, [pc, #0x190]          ; <+636>
    0x89fb60 <+232>: add    r0, pc, r0
    0x89fb64 <+236>: str    r0, [sp, #0x4]
    0x89fb68 <+240>: mov    r0, #21
    0x89fb6c <+244>: str    r0, [sp, #0x8]
    0x89fb70 <+248>: bl     0x8a4950                  ; runtime.printstring
    0x89fb74 <+252>: bl     0x8a401c                  ; runtime.printsp
    0x89fb78 <+256>: ldr    r11, [pc, #0x178]         ; <+640>
    0x89fb7c <+260>: add    r11, pc, r11
    0x89fb80 <+264>: ldr    r4, [r11]
    0x89fb84 <+268>: asr    r3, r4, #31
    0x89fb88 <+272>: mov    r1, r4
    0x89fb8c <+276>: mov    r2, r3
    0x89fb90 <+280>: str    r4, [sp, #0x4]
    0x89fb94 <+284>: str    r3, [sp, #0x8]
    0x89fb98 <+288>: bl     0x8a46e8                  ; runtime.printint
    0x89fb9c <+292>: bl     0x8a401c                  ; runtime.printsp
    0x89fba0 <+296>: ldr    r0, [pc, #0x154]          ; <+644>
    0x89fba4 <+300>: add    r0, pc, r0
    0x89fba8 <+304>: str    r0, [sp, #0x4]
    0x89fbac <+308>: mov    r0, #11
    0x89fbb0 <+312>: str    r0, [sp, #0x8]
    0x89fbb4 <+316>: bl     0x8a4950                  ; runtime.printstring
    0x89fbb8 <+320>: bl     0x8a401c                  ; runtime.printsp
    0x89fbbc <+324>: ldr    r4, [sp, #0x2c]
    0x89fbc0 <+328>: asr    r3, r4, #31
    0x89fbc4 <+332>: mov    r1, r4
    0x89fbc8 <+336>: mov    r2, r3
    0x89fbcc <+340>: str    r4, [sp, #0x4]
    0x89fbd0 <+344>: str    r3, [sp, #0x8]
    0x89fbd4 <+348>: bl     0x8a46e8                  ; runtime.printint
    0x89fbd8 <+352>: bl     0x8a4064                  ; runtime.printnl
    0x89fbdc <+356>: bl     0x8a3e74                  ; runtime.printunlock
    0x89fbe0 <+360>: ldr    r0, [pc, #0x118]          ; <+648>
    0x89fbe4 <+364>: add    r0, pc, r0
    0x89fbe8 <+368>: str    r0, [sp, #0x4]
    0x89fbec <+372>: mov    r0, #13
    0x89fbf0 <+376>: str    r0, [sp, #0x8]
    0x89fbf4 <+380>: bl     0x8a3494                  ; runtime.throw
    0x89fbf8 <+384>: b      0x89faf8                  ; <+128>
    0x89fbfc <+388>: mov    r0, #0
    0x89fc00 <+392>: str    r0, [sp, #0x28]
    0x89fc04 <+396>: mov    r4, #0
    0x89fc08 <+400>: str    r5, [sp, #0x20]
    0x89fc0c <+404>: mov    r1, r4
    0x89fc10 <+408>: cmp    r5, r4
    0x89fc14 <+412>: ble    0x89fcb0                  ; <+568>
    0x89fc18 <+416>: add    r0, sp, #60
    0x89fc1c <+420>: str    r4, [sp, #0x24]
    0x89fc20 <+424>: mov    r1, r4
    0x89fc24 <+428>: mov    r2, #64
    0x89fc28 <+432>: cmp    r4, r2
    0x89fc2c <+436>: blo    0x89fc38                  ; <+448>
    0x89fc30 <+440>: bl     0x8a10cc                  ; runtime.panicindex
    0x89fc34 <+444>: .long  0xf7fabcfd                ; unknown opcode
    0x89fc38 <+448>: mov    r2, #20
    0x89fc3c <+452>: mul    r1, r4, r2
    0x89fc40 <+456>: add    r3, r0, r1
    0x89fc44 <+460>: mov    r2, #0
    0x89fc48 <+464>: ldrsh  r0, [r3, #4]
    0x89fc4c <+468>: mvn    r11, #0
    0x89fc50 <+472>: cmp    r0, r11
    0x89fc54 <+476>: bne    0x89fc60                  ; <+488>
    0x89fc58 <+480>: mov    r1, #114
    0x89fc5c <+484>: add    r2, r2, r1
    0x89fc60 <+488>: ldrsh  r0, [r3, #4]
    0x89fc64 <+492>: mvn    r11, #1
    0x89fc68 <+496>: cmp    r0, r11
    0x89fc6c <+500>: bne    0x89fc78                  ; <+512>
    0x89fc70 <+504>: mov    r1, #119
    0x89fc74 <+508>: add    r2, r2, r1
    0x89fc78 <+512>: cmp    r2, #0
    0x89fc7c <+516>: beq    0x89fca0                  ; <+552>
    0x89fc80 <+520>: add    r0, sp, #40
    0x89fc84 <+524>: str    r0, [sp, #0x4]
    0x89fc88 <+528>: ldr    r1, [r3, #0x10]
    0x89fc8c <+532>: str    r1, [sp, #0x8]
    0x89fc90 <+536>: str    r2, [sp, #0xc]
    0x89fc94 <+540>: bl     0x89ede4                  ; runtime.netpollready
    0x89fc98 <+544>: ldr    r5, [sp, #0x20]
    0x89fc9c <+548>: ldr    r4, [sp, #0x24]
    0x89fca0 <+552>: mov    r2, r4
    0x89fca4 <+556>: mov    r1, #1
    0x89fca8 <+560>: add    r4, r4, r1
    0x89fcac <+564>: b      0x89fc08                  ; <+400>
    0x89fcb0 <+568>: ldrb   r0, [sp, #0x540]
    0x89fcb4 <+572>: cmp    r0, #0
    0x89fcb8 <+576>: beq    0x89fcc8                  ; <+592>
    0x89fcbc <+580>: ldr    r0, [sp, #0x28]
    0x89fcc0 <+584>: cmp    r0, #0
    0x89fcc4 <+588>: beq    0x89faf8                  ; <+128>
    0x89fcc8 <+592>: ldr    r2, [sp, #0x28]
    0x89fccc <+596>: mov    r0, #0
    0x89fcd0 <+600>: str    r2, [sp, #0x544]
    0x89fcd4 <+604>: ldr    pc, [sp], #1340
    0x89fcd8 <+608>: mov    r3, lr
    0x89fcdc <+612>: bl     0x8d4054                  ; runtime.morestack_noctxt
    0x89fce0 <+616>: b      0x89fa78                  ; <+0>
    0x89fce4 <+620>: b      0x89fce4                  ; <+620>
    0x89fce8 <+624>: .long  0xfffffac4                ; unknown opcode
    0x89fcec <+628>: .long  0x0053109c                ; unknown opcode
    0x89fcf0 <+632>: subseq r1, r3, r8, lsr r0
    0x89fcf4 <+636>: eorseq r4, r10, r9, asr #9
    0x89fcf8 <+640>: ldrheq r0, [r3], #-248
    0x89fcfc <+644>: eorseq r0, r10, r1, ror #7
    0x89fd00 <+648>: eorseq r0, r10, r8, lsl #31
runtime.findrunnable:
    0x8aa7d4 <+0>:    ldr    r1, [r10, #0x8]
    0x8aa7d8 <+4>:    cmp    sp, r1
    0x8aa7dc <+8>:    bls    0x8ab31c                  ; <+2888>
    0x8aa7e0 <+12>:   str    lr, [sp, #-0x80]!
    0x8aa7e4 <+16>:   mov    r0, #0
    0x8aa7e8 <+20>:   mov    r0, #0
    0x8aa7ec <+24>:   mov    r0, #0
    0x8aa7f0 <+28>:   mov    r0, #0
    0x8aa7f4 <+32>:   str    r10, [sp, #0x7c]
    0x8aa7f8 <+36>:   ldr    r0, [sp, #0x7c]
    0x8aa7fc <+40>:   ldr    r0, [r0, #0x18]
    0x8aa800 <+44>:   ldr    r2, [r0, #0x58]
    0x8aa804 <+48>:   mov    r0, #0
    0x8aa808 <+52>:   mov    r1, r2
    0x8aa80c <+56>:   str    r2, [sp, #0x78]
    0x8aa810 <+60>:   ldr    r11, [pc, #0x780]         ; <+1988>
    0x8aa814 <+64>:   add    r11, pc, r11
    0x8aa818 <+68>:   ldr    r0, [r11]
    0x8aa81c <+72>:   cmp    r0, #0
    0x8aa820 <+76>:   beq    0x8aa82c                  ; <+88>
    0x8aa824 <+80>:   bl     0x8aa464                  ; runtime.gcstopm
    0x8aa828 <+84>:   b      0x8aa7f8                  ; <+36>
    0x8aa82c <+88>:   ldr    r1, [sp, #0x78]
    0x8aa830 <+92>:   ldr    r0, [r1, #0x944]
    0x8aa834 <+96>:   cmp    r0, #0
    0x8aa838 <+100>:  beq    0x8aa840                  ; <+108>
    0x8aa83c <+104>:  bl     0x8a8d68                  ; runtime.runSafePointFn
    0x8aa840 <+108>:  ldr    r11, [pc, #0x754]         ; <+1992>
    0x8aa844 <+112>:  add    r11, pc, r11
    0x8aa848 <+116>:  ldrb   r0, [r11]
    0x8aa84c <+120>:  cmp    r0, #0
    0x8aa850 <+124>:  beq    0x8aa894                  ; <+192>
    0x8aa854 <+128>:  ldr    r11, [pc, #0x744]         ; <+1996>
    0x8aa858 <+132>:  add    r11, pc, r11
    0x8aa85c <+136>:  ldrb   r0, [r11]
    0x8aa860 <+140>:  cmp    r0, #0
    0x8aa864 <+144>:  beq    0x8aa894                  ; <+192>
    0x8aa868 <+148>:  bl     0x888448                  ; runtime.wakefing
    0x8aa86c <+152>:  ldr    r2, [sp, #0x4]
    0x8aa870 <+156>:  mov    r1, #0
    0x8aa874 <+160>:  cmp    r2, r1
    0x8aa878 <+164>:  beq    0x8aa894                  ; <+192>
    0x8aa87c <+168>:  str    r2, [sp, #0x4]
    0x8aa880 <+172>:  mov    r0, #0
    0x8aa884 <+176>:  str    r0, [sp, #0x8]
    0x8aa888 <+180>:  mov    r0, #1
    0x8aa88c <+184>:  strb   r0, [sp, #0xc]
    0x8aa890 <+188>:  bl     0x8a6a58                  ; runtime.ready
    0x8aa894 <+192>:  ldr    r0, [sp, #0x78]
    0x8aa898 <+196>:  str    r0, [sp, #0x4]
    0x8aa89c <+200>:  bl     0x8b28a0                  ; runtime.runqget
    0x8aa8a0 <+204>:  ldr    r2, [sp, #0x8]
    0x8aa8a4 <+208>:  ldrb   r3, [sp, #0xc]
    0x8aa8a8 <+212>:  mov    r1, #0
    0x8aa8ac <+216>:  cmp    r2, r1
    0x8aa8b0 <+220>:  beq    0x8aa8c4                  ; <+240>
    0x8aa8b4 <+224>:  str    r2, [sp, #0x84]
    0x8aa8b8 <+228>:  and    r0, r3, #255
    0x8aa8bc <+232>:  strb   r0, [sp, #0x88]
    0x8aa8c0 <+236>:  ldr    pc, [sp], #128
    0x8aa8c4 <+240>:  ldr    r11, [pc, #0x6d8]         ; <+2000>
    0x8aa8c8 <+244>:  add    r11, pc, r11
    0x8aa8cc <+248>:  ldr    r0, [r11]
    0x8aa8d0 <+252>:  cmp    r0, #0
    0x8aa8d4 <+256>:  beq    0x8aa954                  ; <+384>
    0x8aa8d8 <+260>:  ldr    r0, [pc, #0x6c8]          ; <+2004>
    0x8aa8dc <+264>:  add    r0, pc, r0
    0x8aa8e0 <+268>:  str    r0, [sp, #0x4]
    0x8aa8e4 <+272>:  ldr    r0, [sp, #0x4]
    0x8aa8e8 <+276>:  mov    r1, #16
    0x8aa8ec <+280>:  add    r0, r0, r1
    0x8aa8f0 <+284>:  str    r0, [sp, #0x4]
    0x8aa8f4 <+288>:  bl     0x87fdb0                  ; runtime.lock
    0x8aa8f8 <+292>:  ldr    r0, [sp, #0x78]
    0x8aa8fc <+296>:  str    r0, [sp, #0x4]
    0x8aa900 <+300>:  mov    r0, #0
    0x8aa904 <+304>:  str    r0, [sp, #0x8]
    0x8aa908 <+308>:  bl     0x8b1fd4                  ; runtime.globrunqget
    0x8aa90c <+312>:  ldr    r0, [sp, #0xc]
    0x8aa910 <+316>:  str    r0, [sp, #0x68]
    0x8aa914 <+320>:  ldr    r0, [pc, #0x690]          ; <+2008>
    0x8aa918 <+324>:  add    r0, pc, r0
    0x8aa91c <+328>:  str    r0, [sp, #0x4]
    0x8aa920 <+332>:  ldr    r0, [sp, #0x4]
    0x8aa924 <+336>:  mov    r1, #16
    0x8aa928 <+340>:  add    r0, r0, r1
    0x8aa92c <+344>:  str    r0, [sp, #0x4]
    0x8aa930 <+348>:  bl     0x880010                  ; runtime.unlock
    0x8aa934 <+352>:  ldr    r2, [sp, #0x68]
    0x8aa938 <+356>:  mov    r1, #0
    0x8aa93c <+360>:  cmp    r2, r1
    0x8aa940 <+364>:  beq    0x8aa954                  ; <+384>
    0x8aa944 <+368>:  str    r2, [sp, #0x84]
    0x8aa948 <+372>:  mov    r0, #0
    0x8aa94c <+376>:  strb   r0, [sp, #0x88]
    0x8aa950 <+380>:  ldr    pc, [sp], #128
    0x8aa954 <+384>:  bl     0x89e018                  ; runtime.netpollinited
    0x8aa958 <+388>:  ldrb   r2, [sp, #0x4]
    0x8aa95c <+392>:  cmp    r2, #0
    0x8aa960 <+396>:  beq    0x8ab318                  ; <+2884>
    0x8aa964 <+400>:  ldr    r11, [pc, #0x644]         ; <+2012>
    0x8aa968 <+404>:  add    r11, pc, r11
    0x8aa96c <+408>:  ldr    r3, [r11]
    0x8aa970 <+412>:  ldr    r11, [pc, #0x63c]         ; <+2016>
    0x8aa974 <+416>:  add    r11, pc, r11
    0x8aa978 <+420>:  ldr    r2, [r11]
    0x8aa97c <+424>:  mov    r1, #0
    0x8aa980 <+428>:  cmp    r2, r1
    0x8aa984 <+432>:  bne    0x8aa994                  ; <+448>
    0x8aa988 <+436>:  mov    r1, #0
    0x8aa98c <+440>:  cmp    r3, r1
    0x8aa990 <+444>:  beq    0x8ab318                  ; <+2884>
    0x8aa994 <+448>:  mov    r0, #0
    0x8aa998 <+452>:  strb   r0, [sp, #0x4]
    0x8aa99c <+456>:  bl     0x89fa78                  ; runtime.netpoll
    0x8aa9a0 <+460>:  ldr    r2, [sp, #0x8]
    0x8aa9a4 <+464>:  mov    r1, #0
    0x8aa9a8 <+468>:  cmp    r2, r1
    0x8aa9ac <+472>:  beq    0x8aaa20                  ; <+588>
    0x8aa9b0 <+476>:  str    r2, [sp, #0x6c]
    0x8aa9b4 <+480>:  ldr    r2, [r2, #0x7c]
    0x8aa9b8 <+484>:  mov    r0, #0
    0x8aa9bc <+488>:  mov    r1, r2
    0x8aa9c0 <+492>:  str    r2, [sp, #0x4]
    0x8aa9c4 <+496>:  bl     0x8ab450                  ; runtime.injectglist
    0x8aa9c8 <+500>:  ldr    r0, [sp, #0x6c]
    0x8aa9cc <+504>:  str    r0, [sp, #0x4]
    0x8aa9d0 <+508>:  mov    r0, #4
    0x8aa9d4 <+512>:  str    r0, [sp, #0x8]
    0x8aa9d8 <+516>:  mov    r0, #1
    0x8aa9dc <+520>:  str    r0, [sp, #0xc]
    0x8aa9e0 <+524>:  bl     0x8a7608                  ; runtime.casgstatus
    0x8aa9e4 <+528>:  ldr    r11, [pc, #0x5cc]         ; <+2020>
    0x8aa9e8 <+532>:  add    r11, pc, r11
    0x8aa9ec <+536>:  ldrsb  r0, [r11]
    0x8aa9f0 <+540>:  cmp    r0, #0
    0x8aa9f4 <+544>:  beq    0x8aaa0c                  ; <+568>
    0x8aa9f8 <+548>:  ldr    r0, [sp, #0x6c]
    0x8aa9fc <+552>:  str    r0, [sp, #0x4]
    0x8aaa00 <+556>:  mov    r0, #0
    0x8aaa04 <+560>:  str    r0, [sp, #0x8]
    0x8aaa08 <+564>:  bl     0x8c6728                  ; runtime.traceGoUnpark
    0x8aaa0c <+568>:  ldr    r0, [sp, #0x6c]
    0x8aaa10 <+572>:  str    r0, [sp, #0x84]
    0x8aaa14 <+576>:  mov    r0, #0
    0x8aaa18 <+580>:  strb   r0, [sp, #0x88]
    0x8aaa1c <+584>:  ldr    pc, [sp], #128
    0x8aaa20 <+588>:  ldr    r11, [pc, #0x594]         ; <+2024>
    0x8aaa24 <+592>:  add    r11, pc, r11
    0x8aaa28 <+596>:  ldr    r0, [r11]
    0x8aaa2c <+600>:  str    r0, [sp, #0x1c]
    0x8aaa30 <+604>:  ldr    r0, [pc, #0x588]          ; <+2028>
    0x8aaa34 <+608>:  add    r0, pc, r0
    0x8aaa38 <+612>:  str    r0, [sp, #0x4]
    0x8aaa3c <+616>:  ldr    r0, [sp, #0x4]
    0x8aaa40 <+620>:  mov    r1, #48
    0x8aaa44 <+624>:  add    r0, r0, r1
    0x8aaa48 <+628>:  str    r0, [sp, #0x4]
    0x8aaa4c <+632>:  bl     0x8fb38c                  ; runtime/internal/atomic.Load
    0x8aaa50 <+636>:  ldr    r4, [sp, #0x7c]
    0x8aaa54 <+640>:  ldr    r2, [sp, #0x8]
    0x8aaa58 <+644>:  ldr    r0, [sp, #0x1c]
    0x8aaa5c <+648>:  mov    r1, #1
    0x8aaa60 <+652>:  sub    r0, r0, r1
    0x8aaa64 <+656>:  cmp    r0, r2
    0x8aaa68 <+660>:  bne    0x8ab078                  ; <+2212>
    0x8aaa6c <+664>:  ldr    r11, [pc, #0x550]         ; <+2032>
    0x8aaa70 <+668>:  add    r11, pc, r11
    0x8aaa74 <+672>:  ldr    r0, [r11]
    0x8aaa78 <+676>:  cmp    r0, #0
    0x8aaa7c <+680>:  beq    0x8aab1c                  ; <+840>
    0x8aaa80 <+684>:  ldr    r1, [sp, #0x78]
    0x8aaa84 <+688>:  ldr    r0, [r1, #0x924]
    0x8aaa88 <+692>:  cmp    r0, #0
    0x8aaa8c <+696>:  beq    0x8aab1c                  ; <+840>
    0x8aaa90 <+700>:  ldr    r0, [sp, #0x78]
    0x8aaa94 <+704>:  str    r0, [sp, #0x4]
    0x8aaa98 <+708>:  bl     0x88d548                  ; runtime.gcMarkWorkAvailable
    0x8aaa9c <+712>:  ldrb   r2, [sp, #0x8]
    0x8aaaa0 <+716>:  cmp    r2, #0
    0x8aaaa4 <+720>:  beq    0x8aab1c                  ; <+840>
    0x8aaaa8 <+724>:  ldr    r0, [sp, #0x78]
    0x8aaaac <+728>:  mov    r1, #2
    0x8aaab0 <+732>:  str    r1, [r0, #0x928]
    0x8aaab4 <+736>:  ldr    r0, [sp, #0x78]
    0x8aaab8 <+740>:  ldr    r2, [r0, #0x924]
    0x8aaabc <+744>:  mov    r0, #0
    0x8aaac0 <+748>:  mov    r1, r2
    0x8aaac4 <+752>:  str    r2, [sp, #0x60]
    0x8aaac8 <+756>:  str    r2, [sp, #0x4]
    0x8aaacc <+760>:  mov    r0, #4
    0x8aaad0 <+764>:  str    r0, [sp, #0x8]
    0x8aaad4 <+768>:  mov    r0, #1
    0x8aaad8 <+772>:  str    r0, [sp, #0xc]
    0x8aaadc <+776>:  bl     0x8a7608                  ; runtime.casgstatus
    0x8aaae0 <+780>:  ldr    r11, [pc, #0x4e0]         ; <+2036>
    0x8aaae4 <+784>:  add    r11, pc, r11
    0x8aaae8 <+788>:  ldrsb  r0, [r11]
    0x8aaaec <+792>:  cmp    r0, #0
    0x8aaaf0 <+796>:  beq    0x8aab08                  ; <+820>
    0x8aaaf4 <+800>:  ldr    r0, [sp, #0x60]
    0x8aaaf8 <+804>:  str    r0, [sp, #0x4]
    0x8aaafc <+808>:  mov    r0, #0
    0x8aab00 <+812>:  str    r0, [sp, #0x8]
    0x8aab04 <+816>:  bl     0x8c6728                  ; runtime.traceGoUnpark
    0x8aab08 <+820>:  ldr    r0, [sp, #0x60]
    0x8aab0c <+824>:  str    r0, [sp, #0x84]
    0x8aab10 <+828>:  mov    r0, #0
    0x8aab14 <+832>:  strb   r0, [sp, #0x88]
    0x8aab18 <+836>:  ldr    pc, [sp], #128
    0x8aab1c <+840>:  ldr    r0, [pc, #0x4a8]          ; <+2040>
    0x8aab20 <+844>:  add    r0, pc, r0
    0x8aab24 <+848>:  str    r0, [sp, #0x4]
    0x8aab28 <+852>:  ldr    r0, [sp, #0x4]
    0x8aab2c <+856>:  mov    r1, #16
    0x8aab30 <+860>:  add    r0, r0, r1
    0x8aab34 <+864>:  str    r0, [sp, #0x4]
    0x8aab38 <+868>:  bl     0x87fdb0                  ; runtime.lock
    0x8aab3c <+872>:  ldr    r2, [sp, #0x78]
    0x8aab40 <+876>:  ldr    r11, [pc, #0x488]         ; <+2044>
    0x8aab44 <+880>:  add    r11, pc, r11
    0x8aab48 <+884>:  ldr    r0, [r11]
    0x8aab4c <+888>:  cmp    r0, #0
    0x8aab50 <+892>:  bne    0x8ab054                  ; <+2176>
    0x8aab54 <+896>:  mov    r1, r2
    0x8aab58 <+900>:  ldr    r0, [r2, #0x944]
    0x8aab5c <+904>:  cmp    r0, #0
    0x8aab60 <+908>:  bne    0x8ab054                  ; <+2176>
    0x8aab64 <+912>:  ldr    r11, [pc, #0x468]         ; <+2048>
    0x8aab68 <+916>:  add    r11, pc, r11
    0x8aab6c <+920>:  ldr    r0, [r11]
    0x8aab70 <+924>:  cmp    r0, #0
    0x8aab74 <+928>:  beq    0x8aabc4                  ; <+1008>
    0x8aab78 <+932>:  str    r2, [sp, #0x4]
    0x8aab7c <+936>:  mov    r0, #0
    0x8aab80 <+940>:  str    r0, [sp, #0x8]
    0x8aab84 <+944>:  bl     0x8b1fd4                  ; runtime.globrunqget
    0x8aab88 <+948>:  ldr    r0, [sp, #0xc]
    0x8aab8c <+952>:  str    r0, [sp, #0x64]
    0x8aab90 <+956>:  ldr    r0, [pc, #0x440]          ; <+2052>
    0x8aab94 <+960>:  add    r0, pc, r0
    0x8aab98 <+964>:  str    r0, [sp, #0x4]
    0x8aab9c <+968>:  ldr    r0, [sp, #0x4]
    0x8aaba0 <+972>:  mov    r1, #16
    0x8aaba4 <+976>:  add    r0, r0, r1
    0x8aaba8 <+980>:  str    r0, [sp, #0x4]
    0x8aabac <+984>:  bl     0x880010                  ; runtime.unlock
    0x8aabb0 <+988>:  ldr    r0, [sp, #0x64]
    0x8aabb4 <+992>:  str    r0, [sp, #0x84]
    0x8aabb8 <+996>:  mov    r0, #0
    0x8aabbc <+1000>: strb   r0, [sp, #0x88]
    0x8aabc0 <+1004>: ldr    pc, [sp], #128
    0x8aabc4 <+1008>: bl     0x8af978                  ; runtime.releasep
    0x8aabc8 <+1012>: ldr    r2, [sp, #0x4]
    0x8aabcc <+1016>: ldr    r1, [sp, #0x78]
    0x8aabd0 <+1020>: cmp    r2, r1
    0x8aabd4 <+1024>: beq    0x8ab050                  ; <+2172>
    0x8aabd8 <+1028>: ldr    r0, [pc, #0x3fc]          ; <+2056>
    0x8aabdc <+1032>: add    r0, pc, r0
    0x8aabe0 <+1036>: str    r0, [sp, #0x4]
    0x8aabe4 <+1040>: mov    r0, #21
    0x8aabe8 <+1044>: str    r0, [sp, #0x8]
    0x8aabec <+1048>: bl     0x8a3494                  ; runtime.throw
    0x8aabf0 <+1052>: ldr    r0, [sp, #0x78]
    0x8aabf4 <+1056>: str    r0, [sp, #0x4]
    0x8aabf8 <+1060>: bl     0x8b2194                  ; runtime.pidleput
    0x8aabfc <+1064>: ldr    r0, [pc, #0x3dc]          ; <+2060>
    0x8aac00 <+1068>: add    r0, pc, r0
    0x8aac04 <+1072>: str    r0, [sp, #0x4]
    0x8aac08 <+1076>: ldr    r0, [sp, #0x4]
    0x8aac0c <+1080>: mov    r1, #16
    0x8aac10 <+1084>: add    r0, r0, r1
    0x8aac14 <+1088>: str    r0, [sp, #0x4]
    0x8aac18 <+1092>: bl     0x880010                  ; runtime.unlock
    0x8aac1c <+1096>: ldr    r2, [sp, #0x7c]
    0x8aac20 <+1100>: ldr    r0, [r2, #0x18]
    0x8aac24 <+1104>: ldrsb  r1, [r0, #136]
    0x8aac28 <+1108>: strb   r1, [sp, #0x18]
    0x8aac2c <+1112>: ldr    r1, [r2, #0x18]
    0x8aac30 <+1116>: ldrsb  r0, [r1, #136]
    0x8aac34 <+1120>: cmp    r0, #0
    0x8aac38 <+1124>: beq    0x8aac94                  ; <+1216>
    0x8aac3c <+1128>: ldr    r1, [r2, #0x18]
    0x8aac40 <+1132>: mov    r0, #0
    0x8aac44 <+1136>: strb   r0, [r1, #0x88]
    0x8aac48 <+1140>: ldr    r0, [pc, #0x394]          ; <+2064>
    0x8aac4c <+1144>: add    r0, pc, r0
    0x8aac50 <+1148>: str    r0, [sp, #0x4]
    0x8aac54 <+1152>: ldr    r0, [sp, #0x4]
    0x8aac58 <+1156>: mov    r1, #52
    0x8aac5c <+1160>: add    r0, r0, r1
    0x8aac60 <+1164>: str    r0, [sp, #0x4]
    0x8aac64 <+1168>: mvn    r0, #0
    0x8aac68 <+1172>: str    r0, [sp, #0x8]
    0x8aac6c <+1176>: bl     0x8fb2c8                  ; runtime/internal/atomic.Xadd
    0x8aac70 <+1180>: ldr    r2, [sp, #0xc]
    0x8aac74 <+1184>: cmp    r2, #0
    0x8aac78 <+1188>: bge    0x8ab04c                  ; <+2168>
    0x8aac7c <+1192>: ldr    r0, [pc, #0x364]          ; <+2068>
    0x8aac80 <+1196>: add    r0, pc, r0
    0x8aac84 <+1200>: str    r0, [sp, #0x4]
    0x8aac88 <+1204>: mov    r0, #33
    0x8aac8c <+1208>: str    r0, [sp, #0x8]
    0x8aac90 <+1212>: bl     0x8a3494                  ; runtime.throw
    0x8aac94 <+1216>: mov    r3, #0
    0x8aac98 <+1220>: ldr    r11, [pc, #0x34c]         ; <+2072>
    0x8aac9c <+1224>: add    r11, pc, r11
    0x8aaca0 <+1228>: ldr    r0, [r11]
    0x8aaca4 <+1232>: mov    r1, r3
    0x8aaca8 <+1236>: cmp    r0, r3
    0x8aacac <+1240>: ble    0x8aadb0                  ; <+1500>
    0x8aacb0 <+1244>: ldr    r0, [pc, #0x338]          ; <+2076>
    0x8aacb4 <+1248>: add    r0, pc, r0
    0x8aacb8 <+1252>: str    r3, [sp, #0x20]
    0x8aacbc <+1256>: mov    r1, r3
    0x8aacc0 <+1260>: ldr    r2, [pc, #0x32c]          ; <+2080>
    0x8aacc4 <+1264>: cmp    r3, r2
    0x8aacc8 <+1268>: blo    0x8aacd4                  ; <+1280>
    0x8aaccc <+1272>: bl     0x8a10cc                  ; runtime.panicindex
    0x8aacd0 <+1276>: .long  0xf7fabcfd                ; unknown opcode
    0x8aacd4 <+1280>: mov    r2, #2
    0x8aacd8 <+1284>: lsl    r1, r3, r2
    0x8aacdc <+1288>: ldr    r2, [r0, r1]
    0x8aace0 <+1292>: mov    r1, #0
    0x8aace4 <+1296>: cmp    r2, r1
    0x8aace8 <+1300>: beq    0x8ab03c                  ; <+2152>
    0x8aacec <+1304>: str    r2, [sp, #0x4]
    0x8aacf0 <+1308>: bl     0x8b22e4                  ; runtime.runqempty
    0x8aacf4 <+1312>: ldr    r3, [sp, #0x20]
    0x8aacf8 <+1316>: ldrb   r2, [sp, #0x8]
    0x8aacfc <+1320>: cmp    r2, #0
    0x8aad00 <+1324>: bne    0x8ab03c                  ; <+2152>
    0x8aad04 <+1328>: ldr    r0, [pc, #0x2ec]          ; <+2084>
    0x8aad08 <+1332>: add    r0, pc, r0
    0x8aad0c <+1336>: str    r0, [sp, #0x4]
    0x8aad10 <+1340>: ldr    r0, [sp, #0x4]
    0x8aad14 <+1344>: mov    r1, #16
    0x8aad18 <+1348>: add    r0, r0, r1
    0x8aad1c <+1352>: str    r0, [sp, #0x4]
    0x8aad20 <+1356>: bl     0x87fdb0                  ; runtime.lock
    0x8aad24 <+1360>: bl     0x8b2250                  ; runtime.pidleget
    0x8aad28 <+1364>: ldr    r0, [sp, #0x4]
    0x8aad2c <+1368>: str    r0, [sp, #0x74]
    0x8aad30 <+1372>: ldr    r0, [pc, #0x2c4]          ; <+2088>
    0x8aad34 <+1376>: add    r0, pc, r0
    0x8aad38 <+1380>: str    r0, [sp, #0x4]
    0x8aad3c <+1384>: ldr    r0, [sp, #0x4]
    0x8aad40 <+1388>: mov    r1, #16
    0x8aad44 <+1392>: add    r0, r0, r1
    0x8aad48 <+1396>: str    r0, [sp, #0x4]
    0x8aad4c <+1400>: bl     0x880010                  ; runtime.unlock
    0x8aad50 <+1404>: ldr    r2, [sp, #0x74]
    0x8aad54 <+1408>: mov    r1, #0
    0x8aad58 <+1412>: cmp    r2, r1
    0x8aad5c <+1416>: beq    0x8aadb0                  ; <+1500>
    0x8aad60 <+1420>: str    r2, [sp, #0x4]
    0x8aad64 <+1424>: bl     0x8af6fc                  ; runtime.acquirep
    0x8aad68 <+1428>: ldrb   r0, [sp, #0x18]
    0x8aad6c <+1432>: cmp    r0, #0
    0x8aad70 <+1436>: beq    0x8aa7f8                  ; <+36>
    0x8aad74 <+1440>: ldr    r0, [sp, #0x7c]
    0x8aad78 <+1444>: ldr    r1, [r0, #0x18]
    0x8aad7c <+1448>: mov    r0, #1
    0x8aad80 <+1452>: strb   r0, [r1, #0x88]
    0x8aad84 <+1456>: ldr    r0, [pc, #0x274]          ; <+2092>
    0x8aad88 <+1460>: add    r0, pc, r0
    0x8aad8c <+1464>: str    r0, [sp, #0x4]
    0x8aad90 <+1468>: ldr    r0, [sp, #0x4]
    0x8aad94 <+1472>: mov    r1, #52
    0x8aad98 <+1476>: add    r0, r0, r1
    0x8aad9c <+1480>: str    r0, [sp, #0x4]
    0x8aada0 <+1484>: mov    r0, #1
    0x8aada4 <+1488>: str    r0, [sp, #0x8]
    0x8aada8 <+1492>: bl     0x8fb2c8                  ; runtime/internal/atomic.Xadd
    0x8aadac <+1496>: b      0x8aa7f8                  ; <+36>
    0x8aadb0 <+1500>: bl     0x89e018                  ; runtime.netpollinited
    0x8aadb4 <+1504>: ldrb   r2, [sp, #0x4]
    0x8aadb8 <+1508>: cmp    r2, #0
    0x8aadbc <+1512>: beq    0x8ab034                  ; <+2144>
    0x8aadc0 <+1516>: ldr    r0, [pc, #0x23c]          ; <+2096>
    0x8aadc4 <+1520>: add    r0, pc, r0
    0x8aadc8 <+1524>: str    r0, [sp, #0x4]
    0x8aadcc <+1528>: ldr    r0, [sp, #0x4]
    0x8aadd0 <+1532>: mov    r1, #8
    0x8aadd4 <+1536>: add    r0, r0, r1
    0x8aadd8 <+1540>: str    r0, [sp, #0x4]
    0x8aaddc <+1544>: mov    r0, #0
    0x8aade0 <+1548>: mov    r1, #0
    0x8aade4 <+1552>: str    r0, [sp, #0x8]
    0x8aade8 <+1556>: str    r1, [sp, #0xc]
    0x8aadec <+1560>: bl     0x8fb6cc                  ; runtime/internal/atomic.Xchg64
    0x8aadf0 <+1564>: ldr    r3, [sp, #0x10]
    0x8aadf4 <+1568>: ldr    r2, [sp, #0x14]
    0x8aadf8 <+1572>: mov    r1, #0
    0x8aadfc <+1576>: cmp    r2, r1
    0x8aae00 <+1580>: bne    0x8aae10                  ; <+1596>
    0x8aae04 <+1584>: mov    r1, #0
    0x8aae08 <+1588>: cmp    r3, r1
    0x8aae0c <+1592>: beq    0x8ab034                  ; <+2144>
    0x8aae10 <+1596>: ldr    r1, [sp, #0x7c]
    0x8aae14 <+1600>: ldr    r1, [r1, #0x18]
    0x8aae18 <+1604>: ldr    r0, [r1, #0x58]
    0x8aae1c <+1608>: cmp    r0, #0
    0x8aae20 <+1612>: beq    0x8aae3c                  ; <+1640>
    0x8aae24 <+1616>: ldr    r0, [pc, #0x1dc]          ; <+2100>
    0x8aae28 <+1620>: add    r0, pc, r0
    0x8aae2c <+1624>: str    r0, [sp, #0x4]
    0x8aae30 <+1628>: mov    r0, #28
    0x8aae34 <+1632>: str    r0, [sp, #0x8]
    0x8aae38 <+1636>: bl     0x8a3494                  ; runtime.throw
    0x8aae3c <+1640>: ldr    r1, [sp, #0x7c]
    0x8aae40 <+1644>: ldr    r1, [r1, #0x18]
    0x8aae44 <+1648>: ldrsb  r0, [r1, #136]
    0x8aae48 <+1652>: cmp    r0, #0
    0x8aae4c <+1656>: beq    0x8aae68                  ; <+1684>
    0x8aae50 <+1660>: ldr    r0, [pc, #0x1b4]          ; <+2104>
    0x8aae54 <+1664>: add    r0, pc, r0
    0x8aae58 <+1668>: str    r0, [sp, #0x4]
    0x8aae5c <+1672>: mov    r0, #35
    0x8aae60 <+1676>: str    r0, [sp, #0x8]
    0x8aae64 <+1680>: bl     0x8a3494                  ; runtime.throw
    0x8aae68 <+1684>: mov    r0, #1
    0x8aae6c <+1688>: strb   r0, [sp, #0x4]
    0x8aae70 <+1692>: bl     0x89fa78                  ; runtime.netpoll
    0x8aae74 <+1696>: ldr    r0, [sp, #0x8]
    0x8aae78 <+1700>: str    r0, [sp, #0x70]
    0x8aae7c <+1704>: bl     0x8d743c                  ; runtime.nanotime
    0x8aae80 <+1708>: ldr    r3, [sp, #0x4]
    0x8aae84 <+1712>: ldr    r2, [sp, #0x8]
    0x8aae88 <+1716>: ldr    r0, [pc, #0x180]          ; <+2108>
    0x8aae8c <+1720>: add    r0, pc, r0
    0x8aae90 <+1724>: str    r0, [sp, #0x4]
    0x8aae94 <+1728>: ldr    r0, [sp, #0x4]
    0x8aae98 <+1732>: mov    r1, #8
    0x8aae9c <+1736>: add    r0, r0, r1
    0x8aaea0 <+1740>: str    r0, [sp, #0x4]
    0x8aaea4 <+1744>: mov    r1, r2
    0x8aaea8 <+1748>: str    r3, [sp, #0x8]
    0x8aaeac <+1752>: str    r2, [sp, #0xc]
    0x8aaeb0 <+1756>: bl     0x8fb91c                  ; runtime/internal/atomic.Store64
    0x8aaeb4 <+1760>: ldr    r0, [sp, #0x70]
    0x8aaeb8 <+1764>: mov    r1, #0
    0x8aaebc <+1768>: cmp    r0, r1
    0x8aaec0 <+1772>: beq    0x8ab02c                  ; <+2136>
    0x8aaec4 <+1776>: ldr    r0, [pc, #0x148]          ; <+2112>
    0x8aaec8 <+1780>: add    r0, pc, r0
    0x8aaecc <+1784>: str    r0, [sp, #0x4]
    0x8aaed0 <+1788>: ldr    r0, [sp, #0x4]
    0x8aaed4 <+1792>: mov    r1, #16
    0x8aaed8 <+1796>: add    r0, r0, r1
    0x8aaedc <+1800>: str    r0, [sp, #0x4]
    0x8aaee0 <+1804>: bl     0x87fdb0                  ; runtime.lock
    0x8aaee4 <+1808>: bl     0x8b2250                  ; runtime.pidleget
    0x8aaee8 <+1812>: ldr    r0, [sp, #0x4]
    0x8aaeec <+1816>: str    r0, [sp, #0x78]
    0x8aaef0 <+1820>: ldr    r0, [pc, #0x120]          ; <+2116>
    0x8aaef4 <+1824>: add    r0, pc, r0
    0x8aaef8 <+1828>: str    r0, [sp, #0x4]
    0x8aaefc <+1832>: ldr    r0, [sp, #0x4]
    0x8aaf00 <+1836>: mov    r1, #16
    0x8aaf04 <+1840>: add    r0, r0, r1
    0x8aaf08 <+1844>: str    r0, [sp, #0x4]
    0x8aaf0c <+1848>: bl     0x880010                  ; runtime.unlock
    0x8aaf10 <+1852>: ldr    r2, [sp, #0x78]
    0x8aaf14 <+1856>: mov    r1, #0
    0x8aaf18 <+1860>: cmp    r2, r1
    0x8aaf1c <+1864>: beq    0x8ab020                  ; <+2124>
    0x8aaf20 <+1868>: str    r2, [sp, #0x4]
    0x8aaf24 <+1872>: bl     0x8af6fc                  ; runtime.acquirep
    0x8aaf28 <+1876>: ldr    r0, [sp, #0x70]
    0x8aaf2c <+1880>: ldr    r2, [r0, #0x7c]
    0x8aaf30 <+1884>: mov    r0, #0
    0x8aaf34 <+1888>: mov    r1, r2
    0x8aaf38 <+1892>: str    r2, [sp, #0x4]
    0x8aaf3c <+1896>: bl     0x8ab450                  ; runtime.injectglist
    0x8aaf40 <+1900>: ldr    r0, [sp, #0x70]
    0x8aaf44 <+1904>: str    r0, [sp, #0x4]
    0x8aaf48 <+1908>: mov    r0, #4
    0x8aaf4c <+1912>: str    r0, [sp, #0x8]
    0x8aaf50 <+1916>: mov    r0, #1
    0x8aaf54 <+1920>: str    r0, [sp, #0xc]
    0x8aaf58 <+1924>: bl     0x8a7608                  ; runtime.casgstatus
    0x8aaf5c <+1928>: ldr    r11, [pc, #0xb8]          ; <+2120>
    0x8aaf60 <+1932>: add    r11, pc, r11
    0x8aaf64 <+1936>: ldrsb  r0, [r11]
    0x8aaf68 <+1940>: cmp    r0, #0
    0x8aaf6c <+1944>: beq    0x8aaf84                  ; <+1968>
    0x8aaf70 <+1948>: ldr    r0, [sp, #0x70]
    0x8aaf74 <+1952>: str    r0, [sp, #0x4]
    0x8aaf78 <+1956>: mov    r0, #0
    0x8aaf7c <+1960>: str    r0, [sp, #0x8]
    0x8aaf80 <+1964>: bl     0x8c6728                  ; runtime.traceGoUnpark
    0x8aaf84 <+1968>: ldr    r0, [sp, #0x70]
    0x8aaf88 <+1972>: str    r0, [sp, #0x84]
    0x8aaf8c <+1976>: mov    r0, #0
    0x8aaf90 <+1980>: strb   r0, [sp, #0x88]
    0x8aaf94 <+1984>: ldr    pc, [sp], #128
    0x8aaf98 <+1988>: subseq r12, r3, r8, lsl #14
    0x8aaf9c <+1992>: .long  0x0054ae96                ; unknown opcode
    0x8aafa0 <+1996>: subseq r10, r4, r3, lsl #29
    0x8aafa4 <+2000>: subseq r12, r3, r0, lsr #12
    0x8aafa8 <+2004>: subseq r12, r3, r12, asr #11
    0x8aafac <+2008>: .long  0x0053c590                ; unknown opcode
    0x8aafb0 <+2012>: subseq r12, r3, r8, asr #10
    0x8aafb4 <+2016>: subseq r12, r3, r0, asr #10
    0x8aafb8 <+2020>: subseq r2, r4, r0, asr #21
    0x8aafbc <+2024>: subseq r10, r4, r8, lsl #27
    0x8aafc0 <+2028>: subseq r12, r3, r4, ror r4
    0x8aafc4 <+2032>: subseq r10, r4, r8, lsr #26
    0x8aafc8 <+2036>: subseq r2, r4, r4, asr #19
    0x8aafcc <+2040>: subseq r12, r3, r8, lsl #7
    0x8aafd0 <+2044>: ldrsbeq r12, [r3], #-56
    0x8aafd4 <+2048>: subseq r12, r3, r0, lsl #7
    0x8aafd8 <+2052>: subseq r12, r3, r4, lsl r3
    0x8aafdc <+2056>: eorseq r9, r9, r10, ror #4
    0x8aafe0 <+2060>: subseq r12, r3, r8, lsr #5
    0x8aafe4 <+2064>: subseq r12, r3, r12, asr r2
    0x8aafe8 <+2068>: eorseq lr, r9, r8, lsr r4
    0x8aafec <+2072>: subseq r10, r4, r0, lsl r11
    0x8aaff0 <+2076>: subseq r12, r3, r4, lsl r9
    0x8aaff4 <+2080>: andeq  r0, r0, r1, lsl #2
    0x8aaff8 <+2084>: subseq r12, r3, r0, lsr #3
    0x8aaffc <+2088>: subseq r12, r3, r4, ror r1
    0x8ab000 <+2092>: subseq r12, r3, r0, lsr #2
    0x8ab004 <+2096>: subseq r12, r3, r4, ror #1
    0x8ab008 <+2100>: eorseq r11, r9, r7, ror lr
    0x8ab00c <+2104>: .long  0x0039efb8                ; unknown opcode
    0x8ab010 <+2108>: subseq r12, r3, r12, lsl r0
    0x8ab014 <+2112>: subseq r11, r3, r0, ror #31
    0x8ab018 <+2116>: ldrheq r11, [r3], #-244
    0x8ab01c <+2120>: subseq r2, r4, r8, asr #10
    0x8ab020 <+2124>: ldr    r0, [sp, #0x70]
    0x8ab024 <+2128>: str    r0, [sp, #0x4]
    0x8ab028 <+2132>: bl     0x8ab450                  ; runtime.injectglist
    0x8ab02c <+2136>: bl     0x8a9898                  ; runtime.stopm
    0x8ab030 <+2140>: b      0x8aa7f8                  ; <+36>
    0x8ab034 <+2144>: bl     0x8a9898                  ; runtime.stopm
    0x8ab038 <+2148>: b      0x8aa7f8                  ; <+36>
    0x8ab03c <+2152>: mov    r2, r3
    0x8ab040 <+2156>: mov    r1, #1
    0x8ab044 <+2160>: add    r3, r3, r1
    0x8ab048 <+2164>: b      0x8aac98                  ; <+1220>
    0x8ab04c <+2168>: b      0x8aac94                  ; <+1216>
    0x8ab050 <+2172>: b      0x8aabf0                  ; <+1052>
    0x8ab054 <+2176>: ldr    r0, [pc, #0x2d0]          ; <+2904>
    0x8ab058 <+2180>: add    r0, pc, r0
    0x8ab05c <+2184>: str    r0, [sp, #0x4]
    0x8ab060 <+2188>: ldr    r0, [sp, #0x4]
    0x8ab064 <+2192>: mov    r1, #16
    0x8ab068 <+2196>: add    r0, r0, r1
    0x8ab06c <+2200>: str    r0, [sp, #0x4]
    0x8ab070 <+2204>: bl     0x880010                  ; runtime.unlock
    0x8ab074 <+2208>: b      0x8aa7f8                  ; <+36>
    0x8ab078 <+2212>: ldr    r1, [r4, #0x18]
    0x8ab07c <+2216>: ldrsb  r0, [r1, #136]
    0x8ab080 <+2220>: cmp    r0, #0
    0x8ab084 <+2224>: bne    0x8ab0f8                  ; <+2340>
    0x8ab088 <+2228>: ldr    r0, [pc, #0x2a0]          ; <+2908>
    0x8ab08c <+2232>: add    r0, pc, r0
    0x8ab090 <+2236>: str    r0, [sp, #0x4]
    0x8ab094 <+2240>: ldr    r0, [sp, #0x4]
    0x8ab098 <+2244>: mov    r1, #52
    0x8ab09c <+2248>: add    r0, r0, r1
    0x8ab0a0 <+2252>: str    r0, [sp, #0x4]
    0x8ab0a4 <+2256>: bl     0x8fb38c                  ; runtime/internal/atomic.Load
    0x8ab0a8 <+2260>: ldr    r0, [sp, #0x8]
    0x8ab0ac <+2264>: str    r0, [sp, #0x28]
    0x8ab0b0 <+2268>: ldr    r0, [pc, #0x27c]          ; <+2912>
    0x8ab0b4 <+2272>: add    r0, pc, r0
    0x8ab0b8 <+2276>: str    r0, [sp, #0x4]
    0x8ab0bc <+2280>: ldr    r0, [sp, #0x4]
    0x8ab0c0 <+2284>: mov    r1, #48
    0x8ab0c4 <+2288>: add    r0, r0, r1
    0x8ab0c8 <+2292>: str    r0, [sp, #0x4]
    0x8ab0cc <+2296>: bl     0x8fb38c                  ; runtime/internal/atomic.Load
    0x8ab0d0 <+2300>: ldr    r4, [sp, #0x7c]
    0x8ab0d4 <+2304>: ldr    r2, [sp, #0x8]
    0x8ab0d8 <+2308>: ldr    r0, [sp, #0x28]
    0x8ab0dc <+2312>: lsl    r0, r0, #1
    0x8ab0e0 <+2316>: ldr    r1, [sp, #0x1c]
    0x8ab0e4 <+2320>: mov    r3, r2
    0x8ab0e8 <+2324>: sub    r1, r1, r2
    0x8ab0ec <+2328>: cmp    r0, r1
    0x8ab0f0 <+2332>: blo    0x8ab0f8                  ; <+2340>
    0x8ab0f4 <+2336>: b      0x8aaa6c                  ; <+664>
    0x8ab0f8 <+2340>: ldr    r1, [r4, #0x18]
    0x8ab0fc <+2344>: ldrsb  r0, [r1, #136]
    0x8ab100 <+2348>: cmp    r0, #0
    0x8ab104 <+2352>: bne    0x8ab13c                  ; <+2408>
    0x8ab108 <+2356>: ldr    r1, [r4, #0x18]
    0x8ab10c <+2360>: mov    r0, #1
    0x8ab110 <+2364>: strb   r0, [r1, #0x88]
    0x8ab114 <+2368>: ldr    r0, [pc, #0x21c]          ; <+2916>
    0x8ab118 <+2372>: add    r0, pc, r0
    0x8ab11c <+2376>: str    r0, [sp, #0x4]
    0x8ab120 <+2380>: ldr    r0, [sp, #0x4]
    0x8ab124 <+2384>: mov    r1, #52
    0x8ab128 <+2388>: add    r0, r0, r1
    0x8ab12c <+2392>: str    r0, [sp, #0x4]
    0x8ab130 <+2396>: mov    r0, #1
    0x8ab134 <+2400>: str    r0, [sp, #0x8]
    0x8ab138 <+2404>: bl     0x8fb2c8                  ; runtime/internal/atomic.Xadd
    0x8ab13c <+2408>: mov    r2, #0
    0x8ab140 <+2412>: str    r2, [sp, #0x24]
    0x8ab144 <+2416>: cmp    r2, #4
    0x8ab148 <+2420>: bge    0x8aaa6c                  ; <+664>
    0x8ab14c <+2424>: ldr    r0, [pc, #0x1e8]          ; <+2920>
    0x8ab150 <+2428>: add    r0, pc, r0
    0x8ab154 <+2432>: str    r0, [sp, #0x5c]
    0x8ab158 <+2436>: bl     0x8d6770                  ; runtime.fastrand1
    0x8ab15c <+2440>: ldr    r4, [sp, #0x5c]
    0x8ab160 <+2444>: ldr    r3, [sp, #0x4]
    0x8ab164 <+2448>: mov    r0, #0
    0x8ab168 <+2452>: ldr    r1, [r4, #0x8]
    0x8ab16c <+2456>: mov    r7, #0
    0x8ab170 <+2460>: ldr    r6, [r4]
    0x8ab174 <+2464>: ldr    r0, [r4]
    0x8ab178 <+2468>: ldr    r11, [r10, #0x18]
    0x8ab17c <+2472>: str    r0, [r11, #0x20]
    0x8ab180 <+2476>: mov    r11, r3
    0x8ab184 <+2480>: bl     0x8d7948                  ; _modu
    0x8ab188 <+2484>: mov    r5, r11
    0x8ab18c <+2488>: ldr    r11, [r10, #0x18]
    0x8ab190 <+2492>: str    r1, [r11, #0x20]
    0x8ab194 <+2496>: mov    r11, r3
    0x8ab198 <+2500>: bl     0x8d7948                  ; _modu
    0x8ab19c <+2504>: mov    r2, r11
    0x8ab1a0 <+2508>: add    r1, r4, #4
    0x8ab1a4 <+2512>: ldr    r3, [r1, #0x4]
    0x8ab1a8 <+2516>: cmp    r2, r3
    0x8ab1ac <+2520>: blo    0x8ab1b8                  ; <+2532>
    0x8ab1b0 <+2524>: bl     0x8a10cc                  ; runtime.panicindex
    0x8ab1b4 <+2528>: .long  0xf7fabcfd                ; unknown opcode
    0x8ab1b8 <+2532>: ldr    r1, [r1]
    0x8ab1bc <+2536>: mov    r3, #2
    0x8ab1c0 <+2540>: lsl    r2, r2, r3
    0x8ab1c4 <+2544>: ldr    r2, [r1, r2]
    0x8ab1c8 <+2548>: str    r7, [sp, #0x4c]
    0x8ab1cc <+2552>: str    r6, [sp, #0x50]
    0x8ab1d0 <+2556>: mov    r4, r6
    0x8ab1d4 <+2560>: str    r5, [sp, #0x54]
    0x8ab1d8 <+2564>: str    r2, [sp, #0x58]
    0x8ab1dc <+2568>: str    r7, [sp, #0x2c]
    0x8ab1e0 <+2572>: str    r7, [sp, #0x3c]
    0x8ab1e4 <+2576>: str    r6, [sp, #0x30]
    0x8ab1e8 <+2580>: str    r6, [sp, #0x40]
    0x8ab1ec <+2584>: str    r5, [sp, #0x34]
    0x8ab1f0 <+2588>: str    r5, [sp, #0x44]
    0x8ab1f4 <+2592>: str    r2, [sp, #0x38]
    0x8ab1f8 <+2596>: str    r2, [sp, #0x48]
    0x8ab1fc <+2600>: add    r3, sp, #60
    0x8ab200 <+2604>: mov    r0, #0
    0x8ab204 <+2608>: ldr    r0, [r3]
    0x8ab208 <+2612>: ldr    r1, [r3, #0x4]
    0x8ab20c <+2616>: cmp    r0, r1
    0x8ab210 <+2620>: beq    0x8ab310                  ; <+2876>
    0x8ab214 <+2624>: mov    r2, #0
    0x8ab218 <+2628>: and    r0, r2, #255
    0x8ab21c <+2632>: cmp    r0, #0
    0x8ab220 <+2636>: bne    0x8ab300                  ; <+2860>
    0x8ab224 <+2640>: ldr    r11, [pc, #0x114]         ; <+2924>
    0x8ab228 <+2644>: add    r11, pc, r11
    0x8ab22c <+2648>: ldr    r0, [r11]
    0x8ab230 <+2652>: cmp    r0, #0
    0x8ab234 <+2656>: bne    0x8aa7f8                  ; <+36>
    0x8ab238 <+2660>: ldr    r0, [sp, #0x24]
    0x8ab23c <+2664>: cmp    r0, #2
    0x8ab240 <+2668>: bgt    0x8ab2f8                  ; <+2852>
    0x8ab244 <+2672>: mov    r3, #0
    0x8ab248 <+2676>: add    r2, sp, #60
    0x8ab24c <+2680>: mov    r0, #0
    0x8ab250 <+2684>: ldr    r1, [r2, #0x8]
    0x8ab254 <+2688>: ldr    r0, [sp, #0x78]
    0x8ab258 <+2692>: str    r0, [sp, #0x4]
    0x8ab25c <+2696>: mov    r0, r1
    0x8ab260 <+2700>: ldr    r1, [pc, #0xdc]           ; <+2928>
    0x8ab264 <+2704>: add    r1, pc, r1
    0x8ab268 <+2708>: ldr    r2, [pc, #0xd8]           ; <+2932>
    0x8ab26c <+2712>: cmp    r0, r2
    0x8ab270 <+2716>: blo    0x8ab27c                  ; <+2728>
    0x8ab274 <+2720>: bl     0x8a10cc                  ; runtime.panicindex
    0x8ab278 <+2724>: .long  0xf7fabcfd                ; unknown opcode
    0x8ab27c <+2728>: mov    r2, #2
    0x8ab280 <+2732>: lsl    r0, r0, r2
    0x8ab284 <+2736>: ldr    r0, [r1, r0]!
    0x8ab288 <+2740>: str    r0, [sp, #0x8]
    0x8ab28c <+2744>: and    r0, r3, #255
    0x8ab290 <+2748>: strb   r0, [sp, #0xc]
    0x8ab294 <+2752>: bl     0x8b2c38                  ; runtime.runqsteal
    0x8ab298 <+2756>: ldr    r2, [sp, #0x10]
    0x8ab29c <+2760>: mov    r1, #0
    0x8ab2a0 <+2764>: cmp    r2, r1
    0x8ab2a4 <+2768>: beq    0x8ab2b8                  ; <+2788>
    0x8ab2a8 <+2772>: str    r2, [sp, #0x84]
    0x8ab2ac <+2776>: mov    r0, #0
    0x8ab2b0 <+2780>: strb   r0, [sp, #0x88]
    0x8ab2b4 <+2784>: ldr    pc, [sp], #128
    0x8ab2b8 <+2788>: add    r3, sp, #60
    0x8ab2bc <+2792>: ldr    r1, [r3]
    0x8ab2c0 <+2796>: mov    r2, #1
    0x8ab2c4 <+2800>: add    r1, r1, r2
    0x8ab2c8 <+2804>: str    r1, [r3]
    0x8ab2cc <+2808>: ldr    r0, [r3, #0x8]
    0x8ab2d0 <+2812>: ldr    r1, [r3, #0xc]
    0x8ab2d4 <+2816>: add    r0, r0, r1
    0x8ab2d8 <+2820>: ldr    r1, [r3, #0x4]
    0x8ab2dc <+2824>: ldr    r11, [r10, #0x18]
    0x8ab2e0 <+2828>: str    r1, [r11, #0x20]
    0x8ab2e4 <+2832>: mov    r11, r0
    0x8ab2e8 <+2836>: bl     0x8d7948                  ; _modu
    0x8ab2ec <+2840>: mov    r0, r11
    0x8ab2f0 <+2844>: str    r0, [r3, #0x8]
    0x8ab2f4 <+2848>: b      0x8ab1fc                  ; <+2600>
    0x8ab2f8 <+2852>: mov    r3, #1
    0x8ab2fc <+2856>: b      0x8ab248                  ; <+2676>
    0x8ab300 <+2860>: ldr    r0, [sp, #0x24]
    0x8ab304 <+2864>: mov    r1, #1
    0x8ab308 <+2868>: add    r2, r0, r1
    0x8ab30c <+2872>: b      0x8ab140                  ; <+2412>
    0x8ab310 <+2876>: mov    r2, #1
    0x8ab314 <+2880>: b      0x8ab218                  ; <+2628>
    0x8ab318 <+2884>: b      0x8aaa20                  ; <+588>
    0x8ab31c <+2888>: mov    r3, lr
    0x8ab320 <+2892>: bl     0x8d4054                  ; runtime.morestack_noctxt
    0x8ab324 <+2896>: b      0x8aa7d4                  ; <+0>
    0x8ab328 <+2900>: b      0x8ab328                  ; <+2900>
    0x8ab32c <+2904>: subseq r11, r3, r0, asr lr
    0x8ab330 <+2908>: subseq r11, r3, r12, lsl lr
    0x8ab334 <+2912>: ldrsheq r11, [r3], #-212
    0x8ab338 <+2916>: .long  0x0053bd90                ; unknown opcode
    0x8ab33c <+2920>: subseq r11, r3, r8, lsr r9
    0x8ab340 <+2924>: ldrsheq r11, [r3], #-196
    0x8ab344 <+2928>: subseq r12, r3, r4, ror #6
    0x8ab348 <+2932>: andeq  r0, r0, r1, lsl #2
runtime.schedule:
    0x8ab688 <+0>:   ldr    r1, [r10, #0x8]
    0x8ab68c <+4>:   cmp    sp, r1
    0x8ab690 <+8>:   bls    0x8ab9c8                  ; <+832>
    0x8ab694 <+12>:  str    lr, [sp, #-0x1c]!
    0x8ab698 <+16>:  str    r10, [sp, #0x18]
    0x8ab69c <+20>:  ldr    r1, [sp, #0x18]
    0x8ab6a0 <+24>:  ldr    r1, [r1, #0x18]
    0x8ab6a4 <+28>:  ldr    r0, [r1, #0x74]
    0x8ab6a8 <+32>:  cmp    r0, #0
    0x8ab6ac <+36>:  beq    0x8ab6c8                  ; <+64>
    0x8ab6b0 <+40>:  ldr    r0, [pc, #0x320]          ; <+848>
    0x8ab6b4 <+44>:  add    r0, pc, r0
    0x8ab6b8 <+48>:  str    r0, [sp, #0x4]
    0x8ab6bc <+52>:  mov    r0, #23
    0x8ab6c0 <+56>:  str    r0, [sp, #0x8]
    0x8ab6c4 <+60>:  bl     0x8a3494                  ; runtime.throw
    0x8ab6c8 <+64>:  ldr    r1, [sp, #0x18]
    0x8ab6cc <+68>:  ldr    r1, [r1, #0x18]
    0x8ab6d0 <+72>:  ldr    r0, [r1, #0xb8]
    0x8ab6d4 <+76>:  mov    r1, #0
    0x8ab6d8 <+80>:  cmp    r0, r1
    0x8ab6dc <+84>:  beq    0x8ab700                  ; <+120>
    0x8ab6e0 <+88>:  bl     0x8aa1e8                  ; runtime.stoplockedm
    0x8ab6e4 <+92>:  ldr    r0, [sp, #0x18]
    0x8ab6e8 <+96>:  ldr    r0, [r0, #0x18]
    0x8ab6ec <+100>: ldr    r1, [r0, #0xb8]
    0x8ab6f0 <+104>: str    r1, [sp, #0x4]
    0x8ab6f4 <+108>: mov    r0, #0
    0x8ab6f8 <+112>: strb   r0, [sp, #0x8]
    0x8ab6fc <+116>: bl     0x8aa604                  ; runtime.execute
    0x8ab700 <+120>: ldr    r11, [pc, #0x2d4]         ; <+852>
    0x8ab704 <+124>: add    r11, pc, r11
    0x8ab708 <+128>: ldr    r0, [r11]
    0x8ab70c <+132>: cmp    r0, #0
    0x8ab710 <+136>: beq    0x8ab72c                  ; <+164>
    0x8ab714 <+140>: bl     0x8aa464                  ; runtime.gcstopm
    0x8ab718 <+144>: ldr    r11, [pc, #0x2c0]         ; <+856>
    0x8ab71c <+148>: add    r11, pc, r11
    0x8ab720 <+152>: ldr    r0, [r11]
    0x8ab724 <+156>: cmp    r0, #0
    0x8ab728 <+160>: bne    0x8ab714                  ; <+140>
    0x8ab72c <+164>: ldr    r0, [sp, #0x18]
    0x8ab730 <+168>: ldr    r0, [r0, #0x18]
    0x8ab734 <+172>: ldr    r1, [r0, #0x58]
    0x8ab738 <+176>: mov    r0, #0
    0x8ab73c <+180>: mov    r2, r1
    0x8ab740 <+184>: ldr    r0, [r1, #0x944]
    0x8ab744 <+188>: cmp    r0, #0
    0x8ab748 <+192>: beq    0x8ab750                  ; <+200>
    0x8ab74c <+196>: bl     0x8a8d68                  ; runtime.runSafePointFn
    0x8ab750 <+200>: mov    r2, #0
    0x8ab754 <+204>: mov    r0, #0
    0x8ab758 <+208>: strb   r0, [sp, #0x10]
    0x8ab75c <+212>: ldr    r11, [pc, #0x280]         ; <+860>
    0x8ab760 <+216>: add    r11, pc, r11
    0x8ab764 <+220>: ldrsb  r0, [r11]
    0x8ab768 <+224>: cmp    r0, #0
    0x8ab76c <+228>: bne    0x8ab97c                  ; <+756>
    0x8ab770 <+232>: ldr    r11, [pc, #0x270]         ; <+864>
    0x8ab774 <+236>: add    r11, pc, r11
    0x8ab778 <+240>: ldrsb  r0, [r11]
    0x8ab77c <+244>: cmp    r0, #0
    0x8ab780 <+248>: bne    0x8ab97c                  ; <+756>
    0x8ab784 <+252>: mov    r1, #0
    0x8ab788 <+256>: cmp    r2, r1
    0x8ab78c <+260>: bne    0x8ab7d0                  ; <+328>
    0x8ab790 <+264>: ldr    r11, [pc, #0x254]         ; <+868>
    0x8ab794 <+268>: add    r11, pc, r11
    0x8ab798 <+272>: ldr    r0, [r11]
    0x8ab79c <+276>: cmp    r0, #0
    0x8ab7a0 <+280>: beq    0x8ab7d0                  ; <+328>
    0x8ab7a4 <+284>: ldr    r0, [sp, #0x18]
    0x8ab7a8 <+288>: ldr    r0, [r0, #0x18]
    0x8ab7ac <+292>: ldr    r2, [r0, #0x58]
    0x8ab7b0 <+296>: mov    r0, #0
    0x8ab7b4 <+300>: mov    r1, r2
    0x8ab7b8 <+304>: ldr    r0, [pc, #0x230]          ; <+872>
    0x8ab7bc <+308>: add    r0, pc, r0
    0x8ab7c0 <+312>: str    r0, [sp, #0x4]
    0x8ab7c4 <+316>: str    r2, [sp, #0x8]
    0x8ab7c8 <+320>: bl     0x88acd4                  ; runtime.(*gcControllerState).findRunnableGCWorker
    0x8ab7cc <+324>: ldr    r2, [sp, #0xc]
    0x8ab7d0 <+328>: mov    r1, #0
    0x8ab7d4 <+332>: cmp    r2, r1
    0x8ab7d8 <+336>: bne    0x8ab898                  ; <+528>
    0x8ab7dc <+340>: ldr    r0, [sp, #0x18]
    0x8ab7e0 <+344>: ldr    r0, [r0, #0x18]
    0x8ab7e4 <+348>: ldr    r1, [r0, #0x58]
    0x8ab7e8 <+352>: mov    r0, #0
    0x8ab7ec <+356>: ldr    r0, [r1, #0x10]
    0x8ab7f0 <+360>: mov    r3, r0
    0x8ab7f4 <+364>: ldr    r1, [pc, #0x1f8]          ; <+876>
    0x8ab7f8 <+368>: umull  r1, r0, r0, r1
    0x8ab7fc <+372>: lsr    r0, r0, #4
    0x8ab800 <+376>: mov    r1, #61
    0x8ab804 <+380>: mul    r0, r1, r0
    0x8ab808 <+384>: sub    r1, r3, r0
    0x8ab80c <+388>: cmp    r1, #0
    0x8ab810 <+392>: bne    0x8ab898                  ; <+528>
    0x8ab814 <+396>: ldr    r11, [pc, #0x1dc]         ; <+880>
    0x8ab818 <+400>: add    r11, pc, r11
    0x8ab81c <+404>: ldr    r0, [r11]
    0x8ab820 <+408>: cmp    r0, #0
    0x8ab824 <+412>: ble    0x8ab898                  ; <+528>
    0x8ab828 <+416>: ldr    r0, [pc, #0x1cc]          ; <+884>
    0x8ab82c <+420>: add    r0, pc, r0
    0x8ab830 <+424>: str    r0, [sp, #0x4]
    0x8ab834 <+428>: ldr    r0, [sp, #0x4]
    0x8ab838 <+432>: mov    r1, #16
    0x8ab83c <+436>: add    r0, r0, r1
    0x8ab840 <+440>: str    r0, [sp, #0x4]
    0x8ab844 <+444>: bl     0x87fdb0                  ; runtime.lock
    0x8ab848 <+448>: ldr    r0, [sp, #0x18]
    0x8ab84c <+452>: ldr    r0, [r0, #0x18]
    0x8ab850 <+456>: ldr    r2, [r0, #0x58]
    0x8ab854 <+460>: mov    r0, #0
    0x8ab858 <+464>: mov    r1, r2
    0x8ab85c <+468>: str    r2, [sp, #0x4]
    0x8ab860 <+472>: mov    r0, #1
    0x8ab864 <+476>: str    r0, [sp, #0x8]
    0x8ab868 <+480>: bl     0x8b1fd4                  ; runtime.globrunqget
    0x8ab86c <+484>: ldr    r0, [sp, #0xc]
    0x8ab870 <+488>: str    r0, [sp, #0x14]
    0x8ab874 <+492>: ldr    r0, [pc, #0x184]          ; <+888>
    0x8ab878 <+496>: add    r0, pc, r0
    0x8ab87c <+500>: str    r0, [sp, #0x4]
    0x8ab880 <+504>: ldr    r0, [sp, #0x4]
    0x8ab884 <+508>: mov    r1, #16
    0x8ab888 <+512>: add    r0, r0, r1
    0x8ab88c <+516>: str    r0, [sp, #0x4]
    0x8ab890 <+520>: bl     0x880010                  ; runtime.unlock
    0x8ab894 <+524>: ldr    r2, [sp, #0x14]
    0x8ab898 <+528>: mov    r1, #0
    0x8ab89c <+532>: cmp    r2, r1
    0x8ab8a0 <+536>: bne    0x8ab90c                  ; <+644>
    0x8ab8a4 <+540>: ldr    r0, [sp, #0x18]
    0x8ab8a8 <+544>: ldr    r0, [r0, #0x18]
    0x8ab8ac <+548>: ldr    r2, [r0, #0x58]
    0x8ab8b0 <+552>: mov    r0, #0
    0x8ab8b4 <+556>: mov    r1, r2
    0x8ab8b8 <+560>: str    r2, [sp, #0x4]
    0x8ab8bc <+564>: bl     0x8b28a0                  ; runtime.runqget
    0x8ab8c0 <+568>: ldr    r2, [sp, #0x8]
    0x8ab8c4 <+572>: ldrb   r0, [sp, #0xc]
    0x8ab8c8 <+576>: strb   r0, [sp, #0x10]
    0x8ab8cc <+580>: str    r2, [sp, #0x14]
    0x8ab8d0 <+584>: mov    r1, #0
    0x8ab8d4 <+588>: cmp    r2, r1
    0x8ab8d8 <+592>: beq    0x8ab90c                  ; <+644>
    0x8ab8dc <+596>: ldr    r1, [sp, #0x18]
    0x8ab8e0 <+600>: ldr    r1, [r1, #0x18]
    0x8ab8e4 <+604>: ldrsb  r0, [r1, #136]
    0x8ab8e8 <+608>: cmp    r0, #0
    0x8ab8ec <+612>: beq    0x8ab90c                  ; <+644>
    0x8ab8f0 <+616>: ldr    r0, [pc, #0x10c]          ; <+892>
    0x8ab8f4 <+620>: add    r0, pc, r0
    0x8ab8f8 <+624>: str    r0, [sp, #0x4]
    0x8ab8fc <+628>: mov    r0, #34
    0x8ab900 <+632>: str    r0, [sp, #0x8]
    0x8ab904 <+636>: bl     0x8a3494                  ; runtime.throw
    0x8ab908 <+640>: ldr    r2, [sp, #0x14]
    0x8ab90c <+644>: str    r2, [sp, #0x14]
    0x8ab910 <+648>: mov    r1, #0
    0x8ab914 <+652>: cmp    r2, r1
    0x8ab918 <+656>: bne    0x8ab930                  ; <+680>
    0x8ab91c <+660>: bl     0x8aa7d4                  ; runtime.findrunnable
    0x8ab920 <+664>: ldr    r2, [sp, #0x4]
    0x8ab924 <+668>: str    r2, [sp, #0x14]
    0x8ab928 <+672>: ldrb   r0, [sp, #0x8]
    0x8ab92c <+676>: strb   r0, [sp, #0x10]
    0x8ab930 <+680>: ldr    r1, [sp, #0x18]
    0x8ab934 <+684>: ldr    r1, [r1, #0x18]
    0x8ab938 <+688>: ldrsb  r0, [r1, #136]
    0x8ab93c <+692>: cmp    r0, #0
    0x8ab940 <+696>: beq    0x8ab94c                  ; <+708>
    0x8ab944 <+700>: bl     0x8ab34c                  ; runtime.resetspinning
    0x8ab948 <+704>: ldr    r2, [sp, #0x14]
    0x8ab94c <+708>: ldr    r0, [r2, #0x9c]
    0x8ab950 <+712>: mov    r1, #0
    0x8ab954 <+716>: cmp    r0, r1
    0x8ab958 <+720>: beq    0x8ab968                  ; <+736>
    0x8ab95c <+724>: str    r2, [sp, #0x4]
    0x8ab960 <+728>: bl     0x8aa37c                  ; runtime.startlockedm
    0x8ab964 <+732>: b      0x8ab700                  ; <+120>
    0x8ab968 <+736>: str    r2, [sp, #0x4]
    0x8ab96c <+740>: ldrb   r0, [sp, #0x10]
    0x8ab970 <+744>: strb   r0, [sp, #0x8]
    0x8ab974 <+748>: bl     0x8aa604                  ; runtime.execute
    0x8ab978 <+752>: ldr    pc, [sp], #28
    0x8ab97c <+756>: bl     0x8c4c4c                  ; runtime.traceReader
    0x8ab980 <+760>: ldr    r2, [sp, #0x4]
    0x8ab984 <+764>: mov    r1, #0
    0x8ab988 <+768>: cmp    r2, r1
    0x8ab98c <+772>: beq    0x8ab784                  ; <+252>
    0x8ab990 <+776>: str    r2, [sp, #0x14]
    0x8ab994 <+780>: str    r2, [sp, #0x4]
    0x8ab998 <+784>: mov    r0, #4
    0x8ab99c <+788>: str    r0, [sp, #0x8]
    0x8ab9a0 <+792>: mov    r0, #1
    0x8ab9a4 <+796>: str    r0, [sp, #0xc]
    0x8ab9a8 <+800>: bl     0x8a7608                  ; runtime.casgstatus
    0x8ab9ac <+804>: ldr    r0, [sp, #0x14]
    0x8ab9b0 <+808>: str    r0, [sp, #0x4]
    0x8ab9b4 <+812>: mov    r0, #0
    0x8ab9b8 <+816>: str    r0, [sp, #0x8]
    0x8ab9bc <+820>: bl     0x8c6728                  ; runtime.traceGoUnpark
    0x8ab9c0 <+824>: ldr    r2, [sp, #0x14]
    0x8ab9c4 <+828>: b      0x8ab784                  ; <+252>
    0x8ab9c8 <+832>: mov    r3, lr
    0x8ab9cc <+836>: bl     0x8d4054                  ; runtime.morestack_noctxt
    0x8ab9d0 <+840>: b      0x8ab688                  ; <+0>
    0x8ab9d4 <+844>: b      0x8ab9d4                  ; <+844>
    0x8ab9d8 <+848>: eorseq r9, r9, r11, lsr #12
    0x8ab9dc <+852>: subseq r11, r3, r8, lsl r8
    0x8ab9e0 <+856>: subseq r11, r3, r0, lsl #16
    0x8ab9e4 <+860>: subseq r1, r4, r8, asr #26
    0x8ab9e8 <+864>: subseq r1, r4, r5, lsr sp
    0x8ab9ec <+868>: subseq r10, r4, r4
    0x8ab9f0 <+872>: subseq r10, r2, r12, lsl r11
    0x8ab9f4 <+876>: .long  0x4325c53f                ; unknown opcode
    0x8ab9f8 <+880>: ldrsbeq r11, [r3], #-96
    0x8ab9fc <+884>: subseq r11, r3, r12, ror r6
    0x8aba00 <+888>: subseq r11, r3, r0, lsr r6
    0x8aba04 <+892>: eorseq lr, r9, r12, lsl r2
runtime.goexit0:
    0x8abe44 <+0>:   ldr    r1, [r10, #0x8]
    0x8abe48 <+4>:   cmp    sp, r1
    0x8abe4c <+8>:   bls    0x8ac088                  ; <+580>
    0x8abe50 <+12>:  str    lr, [sp, #-0x18]!
    0x8abe54 <+16>:  str    r10, [sp, #0x14]
    0x8abe58 <+20>:  ldr    r0, [sp, #0x1c]
    0x8abe5c <+24>:  str    r0, [sp, #0x4]
    0x8abe60 <+28>:  mov    r0, #2
    0x8abe64 <+32>:  str    r0, [sp, #0x8]
    0x8abe68 <+36>:  mov    r0, #6
    0x8abe6c <+40>:  str    r0, [sp, #0xc]
    0x8abe70 <+44>:  bl     0x8a7608                  ; runtime.casgstatus
    0x8abe74 <+48>:  ldr    r4, [sp, #0x14]
    0x8abe78 <+52>:  ldr    r2, [sp, #0x1c]
    0x8abe7c <+56>:  mov    r0, #0
    0x8abe80 <+60>:  ldr    r3, [r2, #0xc0]
    0x8abe84 <+64>:  ldr    r11, [pc, #0x20c]         ; <+596>
    0x8abe88 <+68>:  add    r11, pc, r11
    0x8abe8c <+72>:  ldr    r1, [r11]
    0x8abe90 <+76>:  cmp    r3, r1
    0x8abe94 <+80>:  bne    0x8ac030                  ; <+492>
    0x8abe98 <+84>:  ldr    r11, [pc, #0x1fc]         ; <+600>
    0x8abe9c <+88>:  add    r11, pc, r11
    0x8abea0 <+92>:  ldrb   r0, [r11]
    0x8abea4 <+96>:  cmp    r0, #0
    0x8abea8 <+100>: bne    0x8ac030                  ; <+492>
    0x8abeac <+104>: mov    r3, #1
    0x8abeb0 <+108>: and    r3, r3, #255
    0x8abeb4 <+112>: cmp    r3, #0
    0x8abeb8 <+116>: beq    0x8abeec                  ; <+168>
    0x8abebc <+120>: ldr    r0, [pc, #0x1dc]          ; <+604>
    0x8abec0 <+124>: add    r0, pc, r0
    0x8abec4 <+128>: str    r0, [sp, #0x4]
    0x8abec8 <+132>: ldr    r0, [sp, #0x4]
    0x8abecc <+136>: mov    r1, #40
    0x8abed0 <+140>: add    r0, r0, r1
    0x8abed4 <+144>: str    r0, [sp, #0x4]
    0x8abed8 <+148>: mvn    r0, #0
    0x8abedc <+152>: str    r0, [sp, #0x8]
    0x8abee0 <+156>: bl     0x8fb2c8                  ; runtime/internal/atomic.Xadd
    0x8abee4 <+160>: ldr    r4, [sp, #0x14]
    0x8abee8 <+164>: ldr    r2, [sp, #0x1c]
    0x8abeec <+168>: mov    r1, #0
    0x8abef0 <+172>: str    r1, [r2, #0x18]
    0x8abef4 <+176>: mov    r1, #0
    0x8abef8 <+180>: str    r1, [r2, #0x9c]
    0x8abefc <+184>: ldr    r1, [r4, #0x18]
    0x8abf00 <+188>: mov    r0, #0
    0x8abf04 <+192>: str    r0, [r1, #0xb8]
    0x8abf08 <+196>: mov    r1, #0
    0x8abf0c <+200>: strb   r1, [r2, #0x81]
    0x8abf10 <+204>: mov    r1, #0
    0x8abf14 <+208>: str    r1, [r2, #0x14]
    0x8abf18 <+212>: mov    r1, #0
    0x8abf1c <+216>: str    r1, [r2, #0x10]
    0x8abf20 <+220>: mov    r1, #0
    0x8abf24 <+224>: str    r1, [r2, #0xa4]
    0x8abf28 <+228>: str    r1, [r2, #0xa8]
    0x8abf2c <+232>: str    r1, [r2, #0xac]
    0x8abf30 <+236>: mov    r1, #0
    0x8abf34 <+240>: str    r1, [r2, #0x74]
    0x8abf38 <+244>: str    r1, [r2, #0x78]
    0x8abf3c <+248>: mov    r1, #0
    0x8abf40 <+252>: str    r1, [r2, #0x58]
    0x8abf44 <+256>: mov    r1, #1
    0x8abf48 <+260>: strb   r1, [r2, #0x84]
    0x8abf4c <+264>: mov    r3, r10
    0x8abf50 <+268>: ldr    r1, [r10, #0x18]
    0x8abf54 <+272>: ldr    r0, [r1, #0x50]
    0x8abf58 <+276>: mov    r1, #0
    0x8abf5c <+280>: str    r1, [r0, #0x18]
    0x8abf60 <+284>: ldr    r1, [r10, #0x18]
    0x8abf64 <+288>: mov    r0, #0
    0x8abf68 <+292>: str    r0, [r1, #0x50]
    0x8abf6c <+296>: ldr    r1, [r4, #0x18]
    0x8abf70 <+300>: ldr    r0, [r1, #0x1c0]
    0x8abf74 <+304>: mvn    r1, #1
    0x8abf78 <+308>: and    r0, r0, r1
    0x8abf7c <+312>: cmp    r0, #0
    0x8abf80 <+316>: beq    0x8ac000                  ; <+444>
    0x8abf84 <+320>: ldr    r0, [r4, #0x18]
    0x8abf88 <+324>: ldr    r1, [r0, #0x1c0]
    0x8abf8c <+328>: str    r1, [sp, #0x10]
    0x8abf90 <+332>: bl     0x8a3de8                  ; runtime.printlock
    0x8abf94 <+336>: ldr    r0, [pc, #0x108]          ; <+608>
    0x8abf98 <+340>: add    r0, pc, r0
    0x8abf9c <+344>: str    r0, [sp, #0x4]
    0x8abfa0 <+348>: mov    r0, #20
    0x8abfa4 <+352>: str    r0, [sp, #0x8]
    0x8abfa8 <+356>: bl     0x8a4950                  ; runtime.printstring
    0x8abfac <+360>: ldr    r1, [sp, #0x10]
    0x8abfb0 <+364>: mov    r2, #0
    0x8abfb4 <+368>: mov    r3, r2
    0x8abfb8 <+372>: str    r1, [sp, #0x4]
    0x8abfbc <+376>: str    r2, [sp, #0x8]
    0x8abfc0 <+380>: bl     0x8a46e8                  ; runtime.printint
    0x8abfc4 <+384>: ldr    r0, [pc, #0xdc]           ; <+612>
    0x8abfc8 <+388>: add    r0, pc, r0
    0x8abfcc <+392>: str    r0, [sp, #0x4]
    0x8abfd0 <+396>: mov    r0, #1
    0x8abfd4 <+400>: str    r0, [sp, #0x8]
    0x8abfd8 <+404>: bl     0x8a4950                  ; runtime.printstring
    0x8abfdc <+408>: bl     0x8a3e74                  ; runtime.printunlock
    0x8abfe0 <+412>: ldr    r0, [pc, #0xc4]           ; <+616>
    0x8abfe4 <+416>: add    r0, pc, r0
    0x8abfe8 <+420>: str    r0, [sp, #0x4]
    0x8abfec <+424>: mov    r0, #27
    0x8abff0 <+428>: str    r0, [sp, #0x8]
    0x8abff4 <+432>: bl     0x8a3494                  ; runtime.throw
    0x8abff8 <+436>: ldr    r4, [sp, #0x14]
    0x8abffc <+440>: ldr    r2, [sp, #0x1c]
    0x8ac000 <+444>: ldr    r1, [r4, #0x18]
    0x8ac004 <+448>: mov    r0, #0
    0x8ac008 <+452>: str    r0, [r1, #0x1c0]
    0x8ac00c <+456>: ldr    r0, [r4, #0x18]
    0x8ac010 <+460>: ldr    r3, [r0, #0x58]
    0x8ac014 <+464>: mov    r0, #0
    0x8ac018 <+468>: mov    r1, r3
    0x8ac01c <+472>: str    r3, [sp, #0x4]
    0x8ac020 <+476>: str    r2, [sp, #0x8]
    0x8ac024 <+480>: bl     0x8ad988                  ; runtime.gfput
    0x8ac028 <+484>: bl     0x8ab688                  ; runtime.schedule
    0x8ac02c <+488>: ldr    pc, [sp], #24
    0x8ac030 <+492>: ldr    r11, [pc, #0x78]          ; <+620>
    0x8ac034 <+496>: add    r11, pc, r11
    0x8ac038 <+500>: ldr    r1, [r11]
    0x8ac03c <+504>: cmp    r3, r1
    0x8ac040 <+508>: beq    0x8abeac                  ; <+104>
    0x8ac044 <+512>: ldr    r11, [pc, #0x68]          ; <+624>
    0x8ac048 <+516>: add    r11, pc, r11
    0x8ac04c <+520>: ldr    r1, [r11]
    0x8ac050 <+524>: cmp    r3, r1
    0x8ac054 <+528>: beq    0x8abeac                  ; <+104>
    0x8ac058 <+532>: ldr    r11, [pc, #0x58]          ; <+628>
    0x8ac05c <+536>: add    r11, pc, r11
    0x8ac060 <+540>: ldr    r1, [r11]
    0x8ac064 <+544>: cmp    r3, r1
    0x8ac068 <+548>: beq    0x8abeac                  ; <+104>
    0x8ac06c <+552>: ldr    r11, [pc, #0x48]          ; <+632>
    0x8ac070 <+556>: add    r11, pc, r11
    0x8ac074 <+560>: ldr    r1, [r11]
    0x8ac078 <+564>: cmp    r3, r1
    0x8ac07c <+568>: beq    0x8abeac                  ; <+104>
    0x8ac080 <+572>: mov    r3, #0
    0x8ac084 <+576>: b      0x8abeb0                  ; <+108>
    0x8ac088 <+580>: mov    r3, lr
    0x8ac08c <+584>: bl     0x8d4054                  ; runtime.morestack_noctxt
    0x8ac090 <+588>: b      0x8abe44                  ; <+0>
    0x8ac094 <+592>: b      0x8ac094                  ; <+592>
    0x8ac098 <+596>: subseq r9, r4, r12, asr r9
    0x8ac09c <+600>: subseq r9, r4, sp, lsr r8
    0x8ac0a0 <+604>: subseq r10, r3, r8, ror #31
    0x8ac0a4 <+608>: .long  0x003979b2                ; unknown opcode
    0x8ac0a8 <+612>: eorseq r1, r9, r8, asr r3
    0x8ac0ac <+616>: eorseq r10, r9, r4, asr #11
    0x8ac0b0 <+620>: subseq r9, r4, r8, lsr #14
    0x8ac0b4 <+624>: subseq r9, r4, r8, asr #14
    0x8ac0b8 <+628>: subseq r9, r4, r0, lsr #15
    0x8ac0bc <+632>: subseq r9, r4, r4, lsr #14
runtime.mcall:
    0x8d3ec0 <+0>:   str    sp, [r10, #0x20]
    0x8d3ec4 <+4>:   str    lr, [r10, #0x24]
    0x8d3ec8 <+8>:   mov    r11, #0
    0x8d3ecc <+12>:  str    r11, [r10, #0x34]
    0x8d3ed0 <+16>:  str    r10, [r10, #0x28]
    0x8d3ed4 <+20>:  mov    r1, r10
    0x8d3ed8 <+24>:  ldr    r8, [r10, #0x18]
    0x8d3edc <+28>:  ldr    r0, [r8]
    0x8d3ee0 <+32>:  bl     0x8d6424                  ; setg
    0x8d3ee4 <+36>:  cmp    r1, r10
    0x8d3ee8 <+40>:  bne    0x8d3ef0                  ; <+48>
    0x8d3eec <+44>:  b      0x8a5e8c                  ; runtime.badmcall
    0x8d3ef0 <+48>:  ldr    r11, [pc, #0x30]          ; <+104>
    0x8d3ef4 <+52>:  add    r11, pc, r11
    0x8d3ef8 <+56>:  ldrsb  r11, [r11]
    0x8d3efc <+60>:  cmp    r11, #0
    0x8d3f00 <+64>:  blne   0x8d779c                  ; runtime.save_g
    0x8d3f04 <+68>:  ldr    r0, [sp, #0x4]
    0x8d3f08 <+72>:  ldr    sp, [r10, #0x20]
    0x8d3f0c <+76>:  sub    sp, sp, #8
    0x8d3f10 <+80>:  str    r1, [sp, #0x4]
    0x8d3f14 <+84>:  mov    r7, r0
    0x8d3f18 <+88>:  ldr    r0, [r0]
    0x8d3f1c <+92>:  blx    r0
    0x8d3f20 <+96>:  b      0x8a5ecc                  ; runtime.badmcall2
    0x8d3f24 <+100>: b      0x8d3f24                  ; <+100>
    0x8d3f28 <+104>: .long  0x004fcbf1                ; unknown opcode

it happened after printing this when running with gctrace enabled:

scvg0: 0 MB released
scvg0: inuse: 3, idle: 0, sys: 4, released: 0, consumed: 3 (MB)

@quentinmit quentinmit added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Sep 29, 2016
@kegsay
Copy link

kegsay commented Oct 27, 2016

Looks like I can reliably reproduce this with a test on this project. The affected test purposefully has a NPE in it to make sure panics return HTTP 500s correctly. The complete trace is:

# github.com/matrix-org/go-neb/server
runtime: unexpected return pc for github.com/matrix-org/go-neb/server.TestProtect.func1 called from 0x0
fatal error: unknown caller pc

runtime stack:
runtime.throw(0x293e80, 0x11)
    /usr/local/go/src/runtime/panic.go:566 +0x95
runtime.gentraceback(0xffffffffffffffff, 0xc42003caa8, 0x0, 0xc420061860, 0x0, 0x0, 0x7fffffff, 0x2b1e38, 0x7fff5fbff618, 0x0, ...)
    /usr/local/go/src/runtime/traceback.go:317 +0x13f6
runtime.copystack(0xc420061860, 0x1000, 0x23f01)
    /usr/local/go/src/runtime/stack.go:902 +0x381
runtime.newstack()
    /usr/local/go/src/runtime/stack.go:1070 +0x370
runtime.morestack()
    /usr/local/go/src/runtime/asm_amd64.s:366 +0x7f

goroutine 19 [copystack]:
runtime.heapBitsSetType(0xc4200aac60, 0x120, 0x110, 0x268800)
    /usr/local/go/src/runtime/mbitmap.go:867 fp=0xc42003cab0 sp=0xc42003caa8
runtime.mallocgc(0x120, 0x268800, 0x1, 0x27aea0)
    /usr/local/go/src/runtime/malloc.go:690 +0x5ba fp=0xc42003cb50 sp=0xc42003cab0
runtime.newarray(0x268800, 0x1, 0xad34696cf0b5a0fb)
    /usr/local/go/src/runtime/malloc.go:798 +0x68 fp=0xc42003cb98 sp=0xc42003cb50
runtime.mapassign1(0x24bb00, 0xc42007cf60, 0xc42003ccf0, 0xc42003cce0)
    /usr/local/go/src/runtime/hashmap.go:466 +0x892 fp=0xc42003cc80 sp=0xc42003cb98
github.com/matrix-org/go-neb/server.Protect.func1.1(0xc4200ec0f0, 0x39c5e0, 0xc420076800)
    /Users/kegan/github/go-neb/src/github.com/matrix-org/go-neb/server/server.go:46 +0xf0 fp=0xc42003cd50 sp=0xc42003cc80
runtime.call32(0x0, 0x2b1a28, 0xc4200a20d0, 0x1800000018)
    /usr/local/go/src/runtime/asm_amd64.s:479 +0x4c fp=0xc42003cd80 sp=0xc42003cd50
panic(0x248620, 0xc42000c100)
    /usr/local/go/src/runtime/panic.go:458 +0x243 fp=0xc42003ce10 sp=0xc42003cd80
runtime.panicindex()
    /usr/local/go/src/runtime/panic.go:27 +0x6d fp=0xc42003ce40 sp=0xc42003ce10
github.com/matrix-org/go-neb/server.TestProtect.func1(0x39c5e0, 0xc420076800, 0xc4200ec0f0)
    /Users/kegan/github/go-neb/src/github.com/matrix-org/go-neb/server/server_test.go:14 +0x1c fp=0xc42003ce48 sp=0xc42003ce40
created by testing.(*T).Run
    /usr/local/go/src/testing/testing.go:646 +0x2ec

goroutine 1 [chan receive]:
testing.(*T).Run(0xc42009e0c0, 0x291f05, 0xb, 0x2b1a38, 0x5df65)
    /usr/local/go/src/testing/testing.go:647 +0x316
testing.RunTests.func1(0xc42009e0c0)
    /usr/local/go/src/testing/testing.go:793 +0x6d
testing.tRunner(0xc42009e0c0, 0xc420051e20)
    /usr/local/go/src/testing/testing.go:610 +0x81
testing.RunTests(0x2b1a58, 0x3aeff0, 0x1, 0x1, 0xf6ab)
    /usr/local/go/src/testing/testing.go:799 +0x2f5
testing.(*M).Run(0xc420051ee8, 0xc420051f28)
    /usr/local/go/src/testing/testing.go:743 +0x85
main.main()
    /var/folders/k_/j1h37g112cq299bwxvmbthb80000gn/T/gb925117572/github.com/matrix-org/go-neb/server/_test/github.com/matrix-org/go-neb/_testmain.go:54 +0xc6

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:2086 +0x1
github.com/matrix-org/go-neb/plugin
github.com/matrix-org/go-neb/services/github/webhook
github.com/matrix-org/go-neb
FATAL: command "test" failed: [/var/folders/k_/j1h37g112cq299bwxvmbthb80000gn/T/gb925117572/github.com/matrix-org/go-neb/server/testmain/_test/server.test]: exit status 2

Running Mac OS X - 10.10.5 (Darwin 14.5.0)

go version go1.7.3 darwin/amd64

@randall77
Copy link
Contributor

000000000021e100 <github.com/matrix-org/go-neb/server.TestProtect.func1>:
  21e100:   48 c7 04 24 00 00 00    movq   $0x0,(%rsp)
  21e107:   00 
  21e108:   e8 b3 b8 e0 ff          callq  299c0 <runtime.panicindex>
  21e10d:   0f 0b                   ud2    
  21e10f:   cc                      int3   

The compiled code for this function is bad. It overwrites its return address with 0.

@randall77 randall77 self-assigned this Oct 27, 2016
@randall77 randall77 added NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Oct 27, 2016
@randall77
Copy link
Contributor

Standalone test case:

package main

type W interface {
    Write([]byte)
}

type F func(W)

func foo(f F) {
    defer func() {
        if r := recover(); r != nil {
            usestack(1000)
        }
    }()
    f(nil)
}

func main() {
    foo(func(w W) {
        var x []string
        w.Write([]byte(x[5]))
    })
}

func usestack(n int) {
    if n == 0 {
        return
    }
    usestack(n - 1)
}

@randall77
Copy link
Contributor

Kind of a strange sequence of errors. It does

f(nil, x[5])

First it stores the nil at 0(SP) for the call to f.
Then it does x[5]. The compiler determines statically that the bounds check will fail, so it elides everything subsequent to that check. That includes the call to f.
So there's no call to f any more, but the write of nil to 0(SP) is still there. The only call left is to panicindex, and that doesn't take any args. So no frame is allocated for this function. The spurious arg store then corrupts the return address.

@randall77
Copy link
Contributor

(f = stringtoslicebyte in the example above)

It seems bad to start writing args to the stack before we know if the call will happen. Maybe we need to evaluate all args first, at least to the point where we know whether they will panic or not.
Or we could declare used stack size at the point where we start writing the args. That seems a harder change.

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/32551 mentions this issue.

gopherbot pushed a commit that referenced this issue Nov 2, 2016
when compiling f(a, b, c), we do something like:
  *(SP+0) = eval(a)
  *(SP+8) = eval(b)
  *(SP+16) = eval(c)
  call f

If one of those evaluations is later determined to unconditionally panic
(say eval(b) in this example), then the call is deadcode eliminated. But
any previous argument write (*(SP+0)=... here) is still around. Becuase
we only compute the size of the outarg area for calls which are still
around at the end of optimization, the space needed for *(SP+0)=v is not
accounted for and thus the outarg area may be too small.

The fix is to make sure that we evaluate any potentially panicing
operation before we write any of the args to the stack. It turns out
that fix is pretty easy, as we already have such a mechanism available
for function args. We just need to extend it to possibly panicing args
as well.

The resulting code (if b and c can panic, but a can't) is:
  tmpb = eval(b)
  *(SP+16) = eval(c)
  *(SP+0) = eval(a)
  *(SP+8) = tmpb
  call f

This change tickled a bug in how we find the arguments for intrinsic
calls, so that latent bug is fixed up as well.

Update #16760.

Change-Id: I0bf5edf370220f82bc036cf2085ecc24f356d166
Reviewed-on: https://go-review.googlesource.com/32551
Reviewed-by: Cherry Zhang <cherryyz@google.com>
@randall77
Copy link
Contributor

I've fixed the problem with the recent reproductions on this issue. The original problem remains undiagnosed. It has the same symptom as the fixed examples, but we are <50% confident that the underlying cause is related.
Any more help on reproducing the original failure on this issue are welcome. Might also be worth trying tip to see if CL 32551 did in fact fix it.

@dcu
Copy link
Author

dcu commented Nov 2, 2016

@randall77 what's an easy way to apply your patch to my local go repo ?
I'd like to try your patch

@randall77
Copy link
Contributor

It was just submitted so the easiest would be to sync to tip.
Yo can also cherry pick it, see the download button on the CL page.

@dcu
Copy link
Author

dcu commented Nov 4, 2016

I'm still seeing a crash on both tip and 1.7 (stable)
We created a little sample to reproduce it consistently on an iOS device here:

https://github.com/AdrianaPineda/FrameworkGOMobileSample

and the code that causes the crash is this one:

https://github.com/dcu/gomobile-sample/blob/master/sample.go#L34

basically, an http request.

To reproduce it we let ran the iOS app in background for a few seconds (30 or more) and then we try to open the app and it crashes.

@eliasnaur
Copy link
Contributor

eliasnaur commented Nov 4, 2016

I managed to reproduce the crash with Go tip and with Xcode 8 and an iPhone 5s running ios 10.0.2 with some fiddling. I managed to cut out the umbrella framework and use the Go-based Sample.framework directly from the sample app.

However, I failed to get a crash log from the crash: I can't reproduce the crash while running in the Xcode debugger, and there are no log entries in Xcode > Window > Devices > View Device Logs.

@dcu, how did you acquire a crash log?

@eliasnaur
Copy link
Contributor

I failed to reproduce the runtime crash in the OP, but I did find a problem with non-Go main programs and SIGPIPE handling (sigh). Consider this program that mimics the behaviour of iOS closing sockets when suspending an app after 30 seconds in the background:

package main

import (
    "log"
    "net"
)   

import "C"

func main() {
    Run()
}

//export Run
func Run() {
    l, err := net.Listen("tcp", ":8000")
    if err != nil {
        log.Fatal(err)
    }
    go func() {
        conn, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        conn.Close()
        l.Close()
    }() 
    conn, err := net.Dial("tcp", "localhost:8000")
    if err != nil {
        log.Fatal(err)
    }
    defer conn.Close()
    if err := conn.(*net.TCPConn).CloseWrite(); err != nil {
        log.Fatal(err)
    }
    log.Println("provoking SIGPIPE")
    for {
        if _, err := conn.Write([]byte("some data")); err != nil {
            log.Printf("write error (as expected): %v\n", err)
            break
        }
    }       
    log.Println("hanging forever")
    select {}
}

Running it with go run sigpipe.go gives me, on Linux and macOS:

$ go run sigpipe.go 
2016/11/05 18:04:57 provoking SIGPIPE
2016/11/05 18:04:57 write error (as expected): write tcp [::1]:40428->[::1]:8000: write: broken pipe
2016/11/05 18:04:57 hanging forever

as expected. If, however, I run the same Go program with a C main program as driver:

#include <stdio.h>

extern void Run();

int main() {
    printf("running Go code\n");
    Run();
    printf("done Go code\n");
    return 0;
}

compile it with go build -buildmode=c-archive -o libsigpipe.a sigpipe.go && clang main.c libsigpipe.a -lpthread and run the resulting binary:

$ ./a.out 
running Go code
2016/11/05 18:06:28 provoking SIGPIPE
$ echo $?
141

the program exits because the SIGPIPE is neither handled by the C program nor the Go program.

This behaviour is documented in os/signal:

Go code built with -buildmode=c-archive or -buildmode=c-shared will not install any other signal handlers by default.

where "any other" refers to synchronous signals. Since SIGPIPE is not a synchronous signal, no handler is installed and the program crashes when receiving SIGPIPE from a broken connection.

Even if documented, I believe this behavior is wrong. Go main programs stop SIGPIPEs from killing the program, and should do so even if linked in as c-archive or c-shared. At the very least when the SIGPIPE originates from a Go-created file descriptor.

Paging Mr Signals, @ianlancetaylor (sorry) for ideas.

@eliasnaur
Copy link
Contributor

eliasnaur commented Nov 5, 2016

A low impact, but non-portable, fix would be to use the SO_NOSIGPIPE socket option for darwin, as described in

https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html

Although then the problem would persist on other platforms with similar SIGPIPE behaviour.

@randall77
Copy link
Contributor

@eliasnaur Could you open a separate issue for the sigpipe problem? Thanks.

@dcu
Copy link
Author

dcu commented Nov 6, 2016

@eliasnaur @randall77 #17393 is probably the same issue

@gopherbot
Copy link
Contributor

CL https://golang.org/cl/32796 mentions this issue.

gopherbot pushed a commit that referenced this issue Nov 18, 2016
Before this CL, Go programs in c-archive or c-shared buildmodes
would not handle SIGPIPE. That leads to surprising behaviour where
writes on a closed pipe or socket would raise SIGPIPE and terminate
the program. This CL changes the Go runtime to handle
SIGPIPE regardless of buildmode. In addition, SIGPIPE from non-Go
code is forwarded.

Fixes #17393
Updates #16760

Change-Id: I155e82020a03a5cdc627a147c27da395662c3fe8
Reviewed-on: https://go-review.googlesource.com/32796
Run-TryBot: Elias Naur <elias.naur@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@eliasnaur
Copy link
Contributor

CL 32796 was reverted (see #18100 for details) so the SIGPIPE fix will not be in Go 1.8. An easy workaround is to call signal.Notify(c, SIGPIPE) to block SIGPIPEs from crashing the program.

@dcu
Copy link
Author

dcu commented Dec 12, 2016

I'll close this one since I can't reproduce it anymore.
#17393 can be used to track the SIGPIPE issue

@dcu dcu closed this as completed Dec 12, 2016
@golang golang locked and limited conversation to collaborators Dec 12, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

8 participants