panic.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. // Copyright 2014 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package runtime
  5. import "unsafe"
  6. var indexError = error(errorString("index out of range"))
  7. func panicindex() {
  8. panic(indexError)
  9. }
  10. var sliceError = error(errorString("slice bounds out of range"))
  11. func panicslice() {
  12. panic(sliceError)
  13. }
  14. var divideError = error(errorString("integer divide by zero"))
  15. func panicdivide() {
  16. panic(divideError)
  17. }
  18. var overflowError = error(errorString("integer overflow"))
  19. func panicoverflow() {
  20. panic(overflowError)
  21. }
  22. var floatError = error(errorString("floating point error"))
  23. func panicfloat() {
  24. panic(floatError)
  25. }
  26. var memoryError = error(errorString("invalid memory address or nil pointer dereference"))
  27. func panicmem() {
  28. panic(memoryError)
  29. }
  30. func throwreturn() {
  31. gothrow("no return at end of a typed function - compiler is broken")
  32. }
  33. func throwinit() {
  34. gothrow("recursive call during initialization - linker skew")
  35. }
  36. // Create a new deferred function fn with siz bytes of arguments.
  37. // The compiler turns a defer statement into a call to this.
  38. //go:nosplit
  39. func deferproc(siz int32, fn *funcval) { // arguments of fn follow fn
  40. // the arguments of fn are in a perilous state. The stack map
  41. // for deferproc does not describe them. So we can't let garbage
  42. // collection or stack copying trigger until we've copied them out
  43. // to somewhere safe. deferproc_m does that. Until deferproc_m,
  44. // we can only call nosplit routines.
  45. argp := uintptr(unsafe.Pointer(&fn))
  46. argp += unsafe.Sizeof(fn)
  47. if GOARCH == "arm" {
  48. argp += ptrSize // skip caller's saved link register
  49. }
  50. mp := acquirem()
  51. mp.scalararg[0] = uintptr(siz)
  52. mp.ptrarg[0] = unsafe.Pointer(fn)
  53. mp.scalararg[1] = argp
  54. mp.scalararg[2] = getcallerpc(unsafe.Pointer(&siz))
  55. if mp.curg != getg() {
  56. // go code on the m stack can't defer
  57. gothrow("defer on m")
  58. }
  59. onM(deferproc_m)
  60. releasem(mp)
  61. // deferproc returns 0 normally.
  62. // a deferred func that stops a panic
  63. // makes the deferproc return 1.
  64. // the code the compiler generates always
  65. // checks the return value and jumps to the
  66. // end of the function if deferproc returns != 0.
  67. return0()
  68. // No code can go here - the C return register has
  69. // been set and must not be clobbered.
  70. }
  71. // Small malloc size classes >= 16 are the multiples of 16: 16, 32, 48, 64, 80, 96, 112, 128, 144, ...
  72. // Each P holds a pool for defers with small arg sizes.
  73. // Assign defer allocations to pools by rounding to 16, to match malloc size classes.
  74. const (
  75. deferHeaderSize = unsafe.Sizeof(_defer{})
  76. minDeferAlloc = (deferHeaderSize + 15) &^ 15
  77. minDeferArgs = minDeferAlloc - deferHeaderSize
  78. )
  79. // defer size class for arg size sz
  80. //go:nosplit
  81. func deferclass(siz uintptr) uintptr {
  82. if siz <= minDeferArgs {
  83. return 0
  84. }
  85. return (siz - minDeferArgs + 15) / 16
  86. }
  87. // total size of memory block for defer with arg size sz
  88. func totaldefersize(siz uintptr) uintptr {
  89. if siz <= minDeferArgs {
  90. return minDeferAlloc
  91. }
  92. return deferHeaderSize + siz
  93. }
  94. // Ensure that defer arg sizes that map to the same defer size class
  95. // also map to the same malloc size class.
  96. func testdefersizes() {
  97. var m [len(p{}.deferpool)]int32
  98. for i := range m {
  99. m[i] = -1
  100. }
  101. for i := uintptr(0); ; i++ {
  102. defersc := deferclass(i)
  103. if defersc >= uintptr(len(m)) {
  104. break
  105. }
  106. siz := goroundupsize(totaldefersize(i))
  107. if m[defersc] < 0 {
  108. m[defersc] = int32(siz)
  109. continue
  110. }
  111. if m[defersc] != int32(siz) {
  112. print("bad defer size class: i=", i, " siz=", siz, " defersc=", defersc, "\n")
  113. gothrow("bad defer size class")
  114. }
  115. }
  116. }
  117. // The arguments associated with a deferred call are stored
  118. // immediately after the _defer header in memory.
  119. //go:nosplit
  120. func deferArgs(d *_defer) unsafe.Pointer {
  121. return add(unsafe.Pointer(d), unsafe.Sizeof(*d))
  122. }
  123. var deferType *_type // type of _defer struct
  124. func init() {
  125. var x interface{}
  126. x = (*_defer)(nil)
  127. deferType = (*(**ptrtype)(unsafe.Pointer(&x))).elem
  128. }
  129. // Allocate a Defer, usually using per-P pool.
  130. // Each defer must be released with freedefer.
  131. // Note: runs on M stack
  132. func newdefer(siz int32) *_defer {
  133. var d *_defer
  134. sc := deferclass(uintptr(siz))
  135. mp := acquirem()
  136. if sc < uintptr(len(p{}.deferpool)) {
  137. pp := mp.p
  138. d = pp.deferpool[sc]
  139. if d != nil {
  140. pp.deferpool[sc] = d.link
  141. }
  142. }
  143. if d == nil {
  144. // Allocate new defer+args.
  145. total := goroundupsize(totaldefersize(uintptr(siz)))
  146. d = (*_defer)(mallocgc(total, deferType, 0))
  147. }
  148. d.siz = siz
  149. gp := mp.curg
  150. d.link = gp._defer
  151. gp._defer = d
  152. releasem(mp)
  153. return d
  154. }
  155. // Free the given defer.
  156. // The defer cannot be used after this call.
  157. //go:nosplit
  158. func freedefer(d *_defer) {
  159. if d._panic != nil {
  160. freedeferpanic()
  161. }
  162. if d.fn != nil {
  163. freedeferfn()
  164. }
  165. sc := deferclass(uintptr(d.siz))
  166. if sc < uintptr(len(p{}.deferpool)) {
  167. mp := acquirem()
  168. pp := mp.p
  169. *d = _defer{}
  170. d.link = pp.deferpool[sc]
  171. pp.deferpool[sc] = d
  172. releasem(mp)
  173. }
  174. }
  175. // Separate function so that it can split stack.
  176. // Windows otherwise runs out of stack space.
  177. func freedeferpanic() {
  178. // _panic must be cleared before d is unlinked from gp.
  179. gothrow("freedefer with d._panic != nil")
  180. }
  181. func freedeferfn() {
  182. // fn must be cleared before d is unlinked from gp.
  183. gothrow("freedefer with d.fn != nil")
  184. }
  185. // Run a deferred function if there is one.
  186. // The compiler inserts a call to this at the end of any
  187. // function which calls defer.
  188. // If there is a deferred function, this will call runtime·jmpdefer,
  189. // which will jump to the deferred function such that it appears
  190. // to have been called by the caller of deferreturn at the point
  191. // just before deferreturn was called. The effect is that deferreturn
  192. // is called again and again until there are no more deferred functions.
  193. // Cannot split the stack because we reuse the caller's frame to
  194. // call the deferred function.
  195. // The single argument isn't actually used - it just has its address
  196. // taken so it can be matched against pending defers.
  197. //go:nosplit
  198. func deferreturn(arg0 uintptr) {
  199. gp := getg()
  200. d := gp._defer
  201. if d == nil {
  202. return
  203. }
  204. argp := uintptr(unsafe.Pointer(&arg0))
  205. if d.argp != argp {
  206. return
  207. }
  208. // Moving arguments around.
  209. // Do not allow preemption here, because the garbage collector
  210. // won't know the form of the arguments until the jmpdefer can
  211. // flip the PC over to fn.
  212. mp := acquirem()
  213. memmove(unsafe.Pointer(argp), deferArgs(d), uintptr(d.siz))
  214. fn := d.fn
  215. d.fn = nil
  216. gp._defer = d.link
  217. freedefer(d)
  218. releasem(mp)
  219. jmpdefer(fn, argp)
  220. }
  221. // Goexit terminates the goroutine that calls it. No other goroutine is affected.
  222. // Goexit runs all deferred calls before terminating the goroutine. Because Goexit
  223. // is not panic, however, any recover calls in those deferred functions will return nil.
  224. //
  225. // Calling Goexit from the main goroutine terminates that goroutine
  226. // without func main returning. Since func main has not returned,
  227. // the program continues execution of other goroutines.
  228. // If all other goroutines exit, the program crashes.
  229. func Goexit() {
  230. // Run all deferred functions for the current goroutine.
  231. // This code is similar to gopanic, see that implementation
  232. // for detailed comments.
  233. gp := getg()
  234. for {
  235. d := gp._defer
  236. if d == nil {
  237. break
  238. }
  239. if d.started {
  240. if d._panic != nil {
  241. d._panic.aborted = true
  242. d._panic = nil
  243. }
  244. d.fn = nil
  245. gp._defer = d.link
  246. freedefer(d)
  247. continue
  248. }
  249. d.started = true
  250. reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
  251. if gp._defer != d {
  252. gothrow("bad defer entry in Goexit")
  253. }
  254. d._panic = nil
  255. d.fn = nil
  256. gp._defer = d.link
  257. freedefer(d)
  258. // Note: we ignore recovers here because Goexit isn't a panic
  259. }
  260. goexit()
  261. }
  262. func canpanic(*g) bool
  263. // Print all currently active panics. Used when crashing.
  264. func printpanics(p *_panic) {
  265. if p.link != nil {
  266. printpanics(p.link)
  267. print("\t")
  268. }
  269. print("panic: ")
  270. printany(p.arg)
  271. if p.recovered {
  272. print(" [recovered]")
  273. }
  274. print("\n")
  275. }
  276. // The implementation of the predeclared function panic.
  277. func gopanic(e interface{}) {
  278. gp := getg()
  279. if gp.m.curg != gp {
  280. gothrow("panic on m stack")
  281. }
  282. // m.softfloat is set during software floating point.
  283. // It increments m.locks to avoid preemption.
  284. // We moved the memory loads out, so there shouldn't be
  285. // any reason for it to panic anymore.
  286. if gp.m.softfloat != 0 {
  287. gp.m.locks--
  288. gp.m.softfloat = 0
  289. gothrow("panic during softfloat")
  290. }
  291. if gp.m.mallocing != 0 {
  292. print("panic: ")
  293. printany(e)
  294. print("\n")
  295. gothrow("panic during malloc")
  296. }
  297. if gp.m.gcing != 0 {
  298. print("panic: ")
  299. printany(e)
  300. print("\n")
  301. gothrow("panic during gc")
  302. }
  303. if gp.m.locks != 0 {
  304. print("panic: ")
  305. printany(e)
  306. print("\n")
  307. gothrow("panic holding locks")
  308. }
  309. var p _panic
  310. p.arg = e
  311. p.link = gp._panic
  312. gp._panic = (*_panic)(noescape(unsafe.Pointer(&p)))
  313. for {
  314. d := gp._defer
  315. if d == nil {
  316. break
  317. }
  318. // If defer was started by earlier panic or Goexit (and, since we're back here, that triggered a new panic),
  319. // take defer off list. The earlier panic or Goexit will not continue running.
  320. if d.started {
  321. if d._panic != nil {
  322. d._panic.aborted = true
  323. }
  324. d._panic = nil
  325. d.fn = nil
  326. gp._defer = d.link
  327. freedefer(d)
  328. continue
  329. }
  330. // Mark defer as started, but keep on list, so that traceback
  331. // can find and update the defer's argument frame if stack growth
  332. // or a garbage collection hapens before reflectcall starts executing d.fn.
  333. d.started = true
  334. // Record the panic that is running the defer.
  335. // If there is a new panic during the deferred call, that panic
  336. // will find d in the list and will mark d._panic (this panic) aborted.
  337. d._panic = (*_panic)(noescape((unsafe.Pointer)(&p)))
  338. p.argp = unsafe.Pointer(getargp(0))
  339. reflectcall(unsafe.Pointer(d.fn), deferArgs(d), uint32(d.siz), uint32(d.siz))
  340. p.argp = nil
  341. // reflectcall did not panic. Remove d.
  342. if gp._defer != d {
  343. gothrow("bad defer entry in panic")
  344. }
  345. d._panic = nil
  346. d.fn = nil
  347. gp._defer = d.link
  348. // trigger shrinkage to test stack copy. See stack_test.go:TestStackPanic
  349. //GC()
  350. pc := d.pc
  351. argp := unsafe.Pointer(d.argp) // must be pointer so it gets adjusted during stack copy
  352. freedefer(d)
  353. if p.recovered {
  354. gp._panic = p.link
  355. // Aborted panics are marked but remain on the g.panic list.
  356. // Remove them from the list.
  357. for gp._panic != nil && gp._panic.aborted {
  358. gp._panic = gp._panic.link
  359. }
  360. if gp._panic == nil { // must be done with signal
  361. gp.sig = 0
  362. }
  363. // Pass information about recovering frame to recovery.
  364. gp.sigcode0 = uintptr(argp)
  365. gp.sigcode1 = pc
  366. mcall(recovery_m)
  367. gothrow("recovery failed") // mcall should not return
  368. }
  369. }
  370. // ran out of deferred calls - old-school panic now
  371. startpanic()
  372. printpanics(gp._panic)
  373. dopanic(0) // should not return
  374. *(*int)(nil) = 0 // not reached
  375. }
  376. // getargp returns the location where the caller
  377. // writes outgoing function call arguments.
  378. //go:nosplit
  379. func getargp(x int) uintptr {
  380. // x is an argument mainly so that we can return its address.
  381. // However, we need to make the function complex enough
  382. // that it won't be inlined. We always pass x = 0, so this code
  383. // does nothing other than keep the compiler from thinking
  384. // the function is simple enough to inline.
  385. if x > 0 {
  386. return getcallersp(unsafe.Pointer(&x)) * 0
  387. }
  388. return uintptr(noescape(unsafe.Pointer(&x)))
  389. }
  390. // The implementation of the predeclared function recover.
  391. // Cannot split the stack because it needs to reliably
  392. // find the stack segment of its caller.
  393. //
  394. // TODO(rsc): Once we commit to CopyStackAlways,
  395. // this doesn't need to be nosplit.
  396. //go:nosplit
  397. func gorecover(argp uintptr) interface{} {
  398. // Must be in a function running as part of a deferred call during the panic.
  399. // Must be called from the topmost function of the call
  400. // (the function used in the defer statement).
  401. // p.argp is the argument pointer of that topmost deferred function call.
  402. // Compare against argp reported by caller.
  403. // If they match, the caller is the one who can recover.
  404. gp := getg()
  405. p := gp._panic
  406. if p != nil && !p.recovered && argp == uintptr(p.argp) {
  407. p.recovered = true
  408. return p.arg
  409. }
  410. return nil
  411. }
  412. //go:nosplit
  413. func startpanic() {
  414. onM_signalok(startpanic_m)
  415. }
  416. //go:nosplit
  417. func dopanic(unused int) {
  418. gp := getg()
  419. mp := acquirem()
  420. mp.ptrarg[0] = unsafe.Pointer(gp)
  421. mp.scalararg[0] = getcallerpc((unsafe.Pointer)(&unused))
  422. mp.scalararg[1] = getcallersp((unsafe.Pointer)(&unused))
  423. onM_signalok(dopanic_m) // should never return
  424. *(*int)(nil) = 0
  425. }
  426. //go:nosplit
  427. func throw(s *byte) {
  428. gp := getg()
  429. if gp.m.throwing == 0 {
  430. gp.m.throwing = 1
  431. }
  432. startpanic()
  433. print("fatal error: ", gostringnocopy(s), "\n")
  434. dopanic(0)
  435. *(*int)(nil) = 0 // not reached
  436. }
  437. //go:nosplit
  438. func gothrow(s string) {
  439. gp := getg()
  440. if gp.m.throwing == 0 {
  441. gp.m.throwing = 1
  442. }
  443. startpanic()
  444. print("fatal error: ", s, "\n")
  445. dopanic(0)
  446. *(*int)(nil) = 0 // not reached
  447. }