File: main.go

package info (click to toggle)
panicparse 2.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 744 kB
  • sloc: sh: 13; makefile: 5
file content (969 lines) | stat: -rw-r--r-- 26,740 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
// Copyright 2017 Marc-Antoine Ruel. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

// panic crashes in various ways.
//
// It is a tool to help test pp, it is used in its unit tests.
//
// To install, run:
//   go install github.com/maruel/panicparse/v2/cmd/panic
//   panic -help
//   panic str |& pp
//
// Some panics require the race detector with -race:
//   go install -race github.com/maruel/panicparse/v2/cmd/panic
//   panic race |& pp
//
// To use with optimization (-N) and inlining (-l) disabled, build with
// -gcflags '-N -l' like:
//   go install -gcflags '-N -l' github.com/maruel/panicparse/v2/cmd/panic
package main

// To add a new panic stack signature, add it to types type below, keeping the
// list ordered by name. If you need utility functions, add it in the section
// below. That's it!

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"runtime"
	"sort"
	"strings"
	"sync"
	"syscall"
	"time"

	"github.com/maruel/panicparse/v2/cmd/panic/internal"
	correct "github.com/maruel/panicparse/v2/cmd/panic/internal/incorrect"
	ùtf8 "github.com/maruel/panicparse/v2/cmd/panic/internal/utf8"
)

func main() {
	if len(os.Args) == 2 {
		switch n := os.Args[1]; n {
		case "-h", "-help", "--help", "help":
			usage()
			os.Exit(0)

		case "dump_commands":
			// Undocumented command to do a raw dump of the supported commands. This
			// is used by unit tests in ../../stack.
			items := make([]string, 0, len(types))
			for n := range types {
				items = append(items, n)
			}
			sort.Strings(items)
			for _, n := range items {
				fmt.Printf("%s\n", n)
			}
			os.Exit(0)

		default:
			if f, ok := types[n]; ok {
				fmt.Printf("GOTRACEBACK=%s\n", os.Getenv("GOTRACEBACK"))
				if n == "simple" {
					// Since the map lookup creates another call stack entry, add a
					// one-off "simple" panic style to test the very minimal case.
					// types["simple"].f is never called.
					panic("simple")
				}
				f.f()
				os.Exit(3)
			}
			fmt.Fprintf(stdErr, "unknown panic style %q\n", n)
			os.Exit(1)
		}
	}
	usage()
	os.Exit(1)
}

// Mocked in test.
var stdErr io.Writer = os.Stderr

// Utility functions.

func panicint(i int) {
	panic(i)
}

func panicfloat64(f float64) {
	panic(f)
}

func panicstr(a string) {
	panic(a)
}

func panicslicestr(a []string) {
	panic(a)
}

func panicArgsElided(a, b, c, d, e, f, g, h, i, j, k int) {
	panic(a)
}

func recurse(i int) {
	if i > 0 {
		recurse(i - 1)
		return
	}
	panic(42)
}

func panicRaceDisabled(name string) {
	help := "'panic %s' can only be used when built with the race detector.\n" +
		"To build, use:\n" +
		"  go install -race github.com/maruel/panicparse/v2/cmd/panic\n"
	fmt.Fprintf(stdErr, help, name)
}

func rerunWithFastCrash() {
	if os.Getenv("GORACE") != "log_path=stderr halt_on_error=1" {
		_ = os.Setenv("GORACE", "log_path=stderr halt_on_error=1")
		/* #nosec G204 */
		c := exec.Command(os.Args[0], os.Args[1:]...)
		c.Stderr = os.Stderr
		if err, ok := c.Run().(*exec.ExitError); ok {
			if status, ok := err.Sys().(syscall.WaitStatus); ok {
				os.Exit(status.ExitStatus())
			}
			os.Exit(1)
		}
		os.Exit(0)
	}
}

// panicDoRaceWrite and panicDoRaceRead are extracted from panicRace() to make
// the stack trace less trivial, but in general folks will do the error with
// this code inlined.
func panicDoRaceWrite(x *int) {
	for i := 0; ; i++ {
		*x = i
	}
}
func panicDoRaceRead(x *int) {
	for i := 0; ; {
		i += *x
	}
}

func panicRace() {
	if !raceEnabled {
		panicRaceDisabled("race")
		return
	}
	rerunWithFastCrash()

	i := 0
	// Do two separate calls so that the 'created at' stacks are different.
	go func() {
		panicDoRaceWrite(&i)
	}()
	go func() {
		panicDoRaceRead(&i)
	}()
	time.Sleep(time.Minute)
}

//go:noinline
func panicChanStruct(x chan struct{}) {
	panic("test")
}

/* TODO(maruel): This is not detected!
func panicRaceUnaligned() {
	if !raceEnabled {
		panicRaceDisabled("race_unaligned")
		return
	}
	rerunWithFastCrash()

	a := [8]byte{}
	b := (*int64)(unsafe.Pointer(&a[0]))
	go func() {
		for i := 0; ; i++ {
			a[4] = byte(i)
		}
	}()
	go func() {
		for {
			*b++
		}
	}()
	time.Sleep(time.Minute)
}
*/

//

// types is all the supported types of panics.
//
// Keep the list sorted.
//
// TODO(maruel): Figure out a way to reliably trigger "(scan)" output:
// - disable automatic GC with runtime.SetGCPercent(-1)
// - a goroutine with a large number of items in the stack
// - large heap to make the scanning process slow enough
// - trigger a manual GC with go runtime.GC()
// - panic in the meantime
// This would still not be deterministic.
//
// TODO(maruel): Figure out a way to reliably trigger sleep output.
var types = map[string]struct {
	desc string
	f    func()
}{
	"args_elided": {
		"too many args in stack line, causing the call arguments to be elided",
		func() {
			panicArgsElided(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)
		},
	},

	"chan_receive": {
		"goroutine blocked on <-c",
		func() {
			c := make(chan bool)
			go func() {
				<-c
				<-c
			}()
			c <- true
			panic(42)
		},
	},

	"chan_send": {
		"goroutine blocked on c<-",
		func() {
			c := make(chan bool)
			go func() {
				c <- true
				c <- true
			}()
			<-c
			panic(42)
		},
	},

	"chan_struct": {
		"panic with an empty chan struct{} as a parameter",
		func() {
			panicChanStruct(nil)
		},
	},

	"float": {
		"panic(4.2)",
		func() {
			panicfloat64(4.2)
		},
	},

	"goroutine_1": {
		"panic in one goroutine",
		func() {
			go func() {
				panicint(42)
			}()
			time.Sleep(time.Minute)
		},
	},

	"goroutine_100": {
		"start 100 goroutines before panicking",
		func() {
			var wg sync.WaitGroup
			for i := 0; i < 100; i++ {
				wg.Add(1)
				go func() {
					wg.Done()
					time.Sleep(time.Minute)
				}()
			}
			wg.Wait()
			panicint(42)
		},
	},

	"goroutine_dedupe_pointers": {
		"start 100 goroutines with different pointers before panicking",
		func() {
			var wg sync.WaitGroup
			for i := 0; i < 100; i++ {
				wg.Add(1)
				go func(b *int) {
					wg.Done()
					time.Sleep(time.Minute)
				}(new(int))
			}
			wg.Wait()
			panicint(42)
		},
	},

	"int": {
		"panic(42)",
		func() {
			panicint(42)
		},
	},

	"locked": {
		"thread locked goroutine via runtime.LockOSThread()",
		func() {
			runtime.LockOSThread()
			panic(42)
		},
	},

	"other": {
		"panics with other package in the call stack, with both exported and unexpected functions",
		func() {
			internal.Callback(func() {
				panic("allo")
			})
		},
	},

	"asleep": {
		"panics with 'all goroutines are asleep - deadlock'",
		func() {
			// When built with the race detector, this hangs. I suspect this is due
			// because the race detector starts a separate goroutine which causes
			// checkdead() to not trigger. See checkdead() in src/runtime/proc.go.
			// https://github.com/golang/go/issues/20588
			//
			// Repro:
			//   go install -race github.com/maruel/panicparse/v2/cmd/panic; panic asleep
			var mu sync.Mutex
			mu.Lock()
			mu.Lock()
		},
	},

	"race": {
		"cause a crash by race detector",
		panicRace,
	},

	/* TODO(maruel): This is not detected!
	"race_unaligned": {
		"cause a crash by race detector with unaligned access",
		panicRaceUnaligned,
	},
	*/

	"stack_cut_off": {
		"recursive calls with too many call lines in traceback, causing higher up calls to missing",
		func() {
			// Observed limit is 99.
			// src/runtime/runtime2.go:const _TracebackMaxFrames = 100
			recurse(100)
		},
	},

	"stack_cut_off_named": {
		"named calls with too many call lines in traceback, causing higher up calls to missing",
		func() {
			// The tool has difficulty with very deep static calls during linking.
			// See https://github.com/golang/go/issues/51814
			recurse497()
		},
	},

	"simple": {
		// This is not used for real, here for documentation.
		"skip the map for a shorter stack trace",
		func() {},
	},

	"slice_str": {
		"panic([]string{\"allo\"}) with cap=2",
		func() {
			a := make([]string, 1, 2)
			a[0] = "allo"
			panicslicestr(a)
		},
	},

	"stdlib": {
		"panics with stdlib in the call stack, with both exported and unexpected functions",
		func() {
			strings.FieldsFunc("a", func(rune) bool {
				panic("allo")
			})
		},
	},

	"stdlib_and_other": {
		"panics with both other and stdlib packages in the call stack",
		func() {
			strings.FieldsFunc("a", func(rune) bool {
				internal.Callback(func() {
					panic("allo")
				})
				return false
			})
		},
	},

	"str": {
		"panic(\"allo\")",
		func() {
			panicstr("allo")
		},
	},

	"mismatched": {
		"mismatched package and directory names",
		func() {
			correct.Panic()
		},
	},

	"utf8": {
		"non-ascii package, struct and method names",
		func() {
			s := ùtf8.Strùct{}
			s.Pànic()
		},
	},
}

func usage() {
	t := `usage: panic <way>

This tool is meant to be used with pp to test different parsing scenarios and
ensure output on different version of the Go toolchain can be successfully
parsed.

Set GOTRACEBACK before running this tool to see how it affects the panic output.

Built with: ` + runtime.Version() + `

Select the way to panic:
`
	_, _ = io.WriteString(stdErr, t)
	names := make([]string, 0, len(types))
	m := 0
	for n := range types {
		names = append(names, n)
		if i := len(n); i > m {
			m = i
		}
	}
	sort.Strings(names)
	for _, n := range names {
		fmt.Fprintf(stdErr, "- %-*s  %s\n", m, n, types[n].desc)
	}
}

//

func recurse00()  { panic("the end") }
func recurse01()  { recurse00() }
func recurse02()  { recurse01() }
func recurse03()  { recurse02() }
func recurse04()  { recurse03() }
func recurse05()  { recurse04() }
func recurse06()  { recurse05() }
func recurse07()  { recurse06() }
func recurse08()  { recurse07() }
func recurse09()  { recurse08() }
func recurse10()  { recurse09() }
func recurse11()  { recurse10() }
func recurse12()  { recurse11() }
func recurse13()  { recurse12() }
func recurse14()  { recurse13() }
func recurse15()  { recurse14() }
func recurse16()  { recurse15() }
func recurse17()  { recurse16() }
func recurse18()  { recurse17() }
func recurse19()  { recurse18() }
func recurse20()  { recurse19() }
func recurse21()  { recurse20() }
func recurse22()  { recurse21() }
func recurse23()  { recurse22() }
func recurse24()  { recurse23() }
func recurse25()  { recurse24() }
func recurse26()  { recurse25() }
func recurse27()  { recurse26() }
func recurse28()  { recurse27() }
func recurse29()  { recurse28() }
func recurse30()  { recurse29() }
func recurse31()  { recurse30() }
func recurse32()  { recurse31() }
func recurse33()  { recurse32() }
func recurse34()  { recurse33() }
func recurse35()  { recurse34() }
func recurse36()  { recurse35() }
func recurse37()  { recurse36() }
func recurse38()  { recurse37() }
func recurse39()  { recurse38() }
func recurse40()  { recurse39() }
func recurse41()  { recurse40() }
func recurse42()  { recurse41() }
func recurse43()  { recurse42() }
func recurse44()  { recurse43() }
func recurse45()  { recurse44() }
func recurse46()  { recurse45() }
func recurse47()  { recurse46() }
func recurse48()  { recurse47() }
func recurse49()  { recurse48() }
func recurse50()  { recurse49() }
func recurse51()  { recurse50() }
func recurse52()  { recurse51() }
func recurse53()  { recurse52() }
func recurse54()  { recurse53() }
func recurse55()  { recurse54() }
func recurse56()  { recurse55() }
func recurse57()  { recurse56() }
func recurse58()  { recurse57() }
func recurse59()  { recurse58() }
func recurse60()  { recurse59() }
func recurse61()  { recurse60() }
func recurse62()  { recurse61() }
func recurse63()  { recurse62() }
func recurse64()  { recurse63() }
func recurse65()  { recurse64() }
func recurse66()  { recurse65() }
func recurse67()  { recurse66() }
func recurse68()  { recurse67() }
func recurse69()  { recurse68() }
func recurse70()  { recurse69() }
func recurse71()  { recurse70() }
func recurse72()  { recurse71() }
func recurse73()  { recurse72() }
func recurse74()  { recurse73() }
func recurse75()  { recurse74() }
func recurse76()  { recurse75() }
func recurse77()  { recurse76() }
func recurse78()  { recurse77() }
func recurse79()  { recurse78() }
func recurse80()  { recurse79() }
func recurse81()  { recurse80() }
func recurse82()  { recurse81() }
func recurse83()  { recurse82() }
func recurse84()  { recurse83() }
func recurse85()  { recurse84() }
func recurse86()  { recurse85() }
func recurse87()  { recurse86() }
func recurse88()  { recurse87() }
func recurse89()  { recurse88() }
func recurse90()  { recurse89() }
func recurse91()  { recurse90() }
func recurse92()  { recurse91() }
func recurse93()  { recurse92() }
func recurse94()  { recurse93() }
func recurse95()  { recurse94() }
func recurse96()  { recurse95() }
func recurse97()  { recurse96() }
func recurse98()  { recurse97() }
func recurse99()  { recurse98() }
func recurse100() { recurse99() }

func recurse101() { recurse100() }
func recurse102() { recurse101() }
func recurse103() { recurse102() }
func recurse104() { recurse103() }
func recurse105() { recurse104() }
func recurse106() { recurse105() }
func recurse107() { recurse106() }
func recurse108() { recurse107() }
func recurse109() { recurse108() }
func recurse110() { recurse109() }
func recurse111() { recurse110() }
func recurse112() { recurse111() }
func recurse113() { recurse112() }
func recurse114() { recurse113() }
func recurse115() { recurse114() }
func recurse116() { recurse115() }
func recurse117() { recurse116() }
func recurse118() { recurse117() }
func recurse119() { recurse118() }
func recurse120() { recurse119() }
func recurse121() { recurse120() }
func recurse122() { recurse121() }
func recurse123() { recurse122() }
func recurse124() { recurse123() }
func recurse125() { recurse124() }
func recurse126() { recurse125() }
func recurse127() { recurse126() }
func recurse128() { recurse127() }
func recurse129() { recurse128() }
func recurse130() { recurse129() }
func recurse131() { recurse130() }
func recurse132() { recurse131() }
func recurse133() { recurse132() }
func recurse134() { recurse133() }
func recurse135() { recurse134() }
func recurse136() { recurse135() }
func recurse137() { recurse136() }
func recurse138() { recurse137() }
func recurse139() { recurse138() }
func recurse140() { recurse139() }
func recurse141() { recurse140() }
func recurse142() { recurse141() }
func recurse143() { recurse142() }
func recurse144() { recurse143() }
func recurse145() { recurse144() }
func recurse146() { recurse145() }
func recurse147() { recurse146() }
func recurse148() { recurse147() }
func recurse149() { recurse148() }
func recurse150() { recurse149() }
func recurse151() { recurse150() }
func recurse152() { recurse151() }
func recurse153() { recurse152() }
func recurse154() { recurse153() }
func recurse155() { recurse154() }
func recurse156() { recurse155() }
func recurse157() { recurse156() }
func recurse158() { recurse157() }
func recurse159() { recurse158() }
func recurse160() { recurse159() }
func recurse161() { recurse160() }
func recurse162() { recurse161() }
func recurse163() { recurse162() }
func recurse164() { recurse163() }
func recurse165() { recurse164() }
func recurse166() { recurse165() }
func recurse167() { recurse166() }
func recurse168() { recurse167() }
func recurse169() { recurse168() }
func recurse170() { recurse169() }
func recurse171() { recurse170() }
func recurse172() { recurse171() }
func recurse173() { recurse172() }
func recurse174() { recurse173() }
func recurse175() { recurse174() }
func recurse176() { recurse175() }
func recurse177() { recurse176() }
func recurse178() { recurse177() }
func recurse179() { recurse178() }
func recurse180() { recurse179() }
func recurse181() { recurse180() }
func recurse182() { recurse181() }
func recurse183() { recurse182() }
func recurse184() { recurse183() }
func recurse185() { recurse184() }
func recurse186() { recurse185() }
func recurse187() { recurse186() }
func recurse188() { recurse187() }
func recurse189() { recurse188() }
func recurse190() { recurse189() }
func recurse191() { recurse190() }
func recurse192() { recurse191() }
func recurse193() { recurse192() }
func recurse194() { recurse193() }
func recurse195() { recurse194() }
func recurse196() { recurse195() }
func recurse197() { recurse196() }
func recurse198() { recurse197() }
func recurse199() { recurse198() }

func recurse200() { recurse199() }
func recurse201() { recurse200() }
func recurse202() { recurse201() }
func recurse203() { recurse202() }
func recurse204() { recurse203() }
func recurse205() { recurse204() }
func recurse206() { recurse205() }
func recurse207() { recurse206() }
func recurse208() { recurse207() }
func recurse209() { recurse208() }
func recurse210() { recurse209() }
func recurse211() { recurse210() }
func recurse212() { recurse211() }
func recurse213() { recurse212() }
func recurse214() { recurse213() }
func recurse215() { recurse214() }
func recurse216() { recurse215() }
func recurse217() { recurse216() }
func recurse218() { recurse217() }
func recurse219() { recurse218() }
func recurse220() { recurse219() }
func recurse221() { recurse220() }
func recurse222() { recurse221() }
func recurse223() { recurse222() }
func recurse224() { recurse223() }
func recurse225() { recurse224() }
func recurse226() { recurse225() }
func recurse227() { recurse226() }
func recurse228() { recurse227() }
func recurse229() { recurse228() }
func recurse230() { recurse229() }
func recurse231() { recurse230() }
func recurse232() { recurse231() }
func recurse233() { recurse232() }
func recurse234() { recurse233() }
func recurse235() { recurse234() }
func recurse236() { recurse235() }
func recurse237() { recurse236() }
func recurse238() { recurse237() }
func recurse239() { recurse238() }
func recurse240() { recurse239() }
func recurse241() { recurse240() }
func recurse242() { recurse241() }
func recurse243() { recurse242() }
func recurse244() { recurse243() }
func recurse245() { recurse244() }
func recurse246() { recurse245() }
func recurse247() { recurse246() }
func recurse248() { recurse247() }
func recurse249() { recurse248() }
func recurse250() { recurse249() }
func recurse251() { recurse250() }
func recurse252() { recurse251() }
func recurse253() { recurse252() }
func recurse254() { recurse253() }
func recurse255() { recurse254() }
func recurse256() { recurse255() }
func recurse257() { recurse256() }
func recurse258() { recurse257() }
func recurse259() { recurse258() }
func recurse260() { recurse259() }
func recurse261() { recurse260() }
func recurse262() { recurse261() }
func recurse263() { recurse262() }
func recurse264() { recurse263() }
func recurse265() { recurse264() }
func recurse266() { recurse265() }
func recurse267() { recurse266() }
func recurse268() { recurse267() }
func recurse269() { recurse268() }
func recurse270() { recurse269() }
func recurse271() { recurse270() }
func recurse272() { recurse271() }
func recurse273() { recurse272() }
func recurse274() { recurse273() }
func recurse275() { recurse274() }
func recurse276() { recurse275() }
func recurse277() { recurse276() }
func recurse278() { recurse277() }
func recurse279() { recurse278() }
func recurse280() { recurse279() }
func recurse281() { recurse280() }
func recurse282() { recurse281() }
func recurse283() { recurse282() }
func recurse284() { recurse283() }
func recurse285() { recurse284() }
func recurse286() { recurse285() }
func recurse287() { recurse286() }
func recurse288() { recurse287() }
func recurse289() { recurse288() }
func recurse290() { recurse289() }
func recurse291() { recurse290() }
func recurse292() { recurse291() }
func recurse293() { recurse292() }
func recurse294() { recurse293() }
func recurse295() { recurse294() }
func recurse296() { recurse295() }
func recurse297() { recurse296() }
func recurse298() { recurse297() }
func recurse299() { recurse298() }

func recurse300() { recurse299() }
func recurse301() { recurse300() }
func recurse302() { recurse301() }
func recurse303() { recurse302() }
func recurse304() { recurse303() }
func recurse305() { recurse304() }
func recurse306() { recurse305() }
func recurse307() { recurse306() }
func recurse308() { recurse307() }
func recurse309() { recurse308() }
func recurse310() { recurse309() }
func recurse311() { recurse310() }
func recurse312() { recurse311() }
func recurse313() { recurse312() }
func recurse314() { recurse313() }
func recurse315() { recurse314() }
func recurse316() { recurse315() }
func recurse317() { recurse316() }
func recurse318() { recurse317() }
func recurse319() { recurse318() }
func recurse320() { recurse319() }
func recurse321() { recurse320() }
func recurse322() { recurse321() }
func recurse323() { recurse322() }
func recurse324() { recurse323() }
func recurse325() { recurse324() }
func recurse326() { recurse325() }
func recurse327() { recurse326() }
func recurse328() { recurse327() }
func recurse329() { recurse328() }
func recurse330() { recurse329() }
func recurse331() { recurse330() }
func recurse332() { recurse331() }
func recurse333() { recurse332() }
func recurse334() { recurse333() }
func recurse335() { recurse334() }
func recurse336() { recurse335() }
func recurse337() { recurse336() }
func recurse338() { recurse337() }
func recurse339() { recurse338() }
func recurse340() { recurse339() }
func recurse341() { recurse340() }
func recurse342() { recurse341() }
func recurse343() { recurse342() }
func recurse344() { recurse343() }
func recurse345() { recurse344() }
func recurse346() { recurse345() }
func recurse347() { recurse346() }
func recurse348() { recurse347() }
func recurse349() { recurse348() }
func recurse350() { recurse349() }
func recurse351() { recurse350() }
func recurse352() { recurse351() }
func recurse353() { recurse352() }
func recurse354() { recurse353() }
func recurse355() { recurse354() }
func recurse356() { recurse355() }
func recurse357() { recurse356() }
func recurse358() { recurse357() }
func recurse359() { recurse358() }
func recurse360() { recurse359() }
func recurse361() { recurse360() }
func recurse362() { recurse361() }
func recurse363() { recurse362() }
func recurse364() { recurse363() }
func recurse365() { recurse364() }
func recurse366() { recurse365() }
func recurse367() { recurse366() }
func recurse368() { recurse367() }
func recurse369() { recurse368() }
func recurse370() { recurse369() }
func recurse371() { recurse370() }
func recurse372() { recurse371() }
func recurse373() { recurse372() }
func recurse374() { recurse373() }
func recurse375() { recurse374() }
func recurse376() { recurse375() }
func recurse377() { recurse376() }
func recurse378() { recurse377() }
func recurse379() { recurse378() }
func recurse380() { recurse379() }
func recurse381() { recurse380() }
func recurse382() { recurse381() }
func recurse383() { recurse382() }
func recurse384() { recurse383() }
func recurse385() { recurse384() }
func recurse386() { recurse385() }
func recurse387() { recurse386() }
func recurse388() { recurse387() }
func recurse389() { recurse388() }
func recurse390() { recurse389() }
func recurse391() { recurse390() }
func recurse392() { recurse391() }
func recurse393() { recurse392() }
func recurse394() { recurse393() }
func recurse395() { recurse394() }
func recurse396() { recurse395() }
func recurse397() { recurse396() }
func recurse398() { recurse397() }
func recurse399() { recurse398() }

func recurse400() { recurse399() }
func recurse401() { recurse400() }
func recurse402() { recurse401() }
func recurse403() { recurse402() }
func recurse404() { recurse403() }
func recurse405() { recurse404() }
func recurse406() { recurse405() }
func recurse407() { recurse406() }
func recurse408() { recurse407() }
func recurse409() { recurse408() }
func recurse410() { recurse409() }
func recurse411() { recurse410() }
func recurse412() { recurse411() }
func recurse413() { recurse412() }
func recurse414() { recurse413() }
func recurse415() { recurse414() }
func recurse416() { recurse415() }
func recurse417() { recurse416() }
func recurse418() { recurse417() }
func recurse419() { recurse418() }
func recurse420() { recurse419() }
func recurse421() { recurse420() }
func recurse422() { recurse421() }
func recurse423() { recurse422() }
func recurse424() { recurse423() }
func recurse425() { recurse424() }
func recurse426() { recurse425() }
func recurse427() { recurse426() }
func recurse428() { recurse427() }
func recurse429() { recurse428() }
func recurse430() { recurse429() }
func recurse431() { recurse430() }
func recurse432() { recurse431() }
func recurse433() { recurse432() }
func recurse434() { recurse433() }
func recurse435() { recurse434() }
func recurse436() { recurse435() }
func recurse437() { recurse436() }
func recurse438() { recurse437() }
func recurse439() { recurse438() }
func recurse440() { recurse439() }
func recurse441() { recurse440() }
func recurse442() { recurse441() }
func recurse443() { recurse442() }
func recurse444() { recurse443() }
func recurse445() { recurse444() }
func recurse446() { recurse445() }
func recurse447() { recurse446() }
func recurse448() { recurse447() }
func recurse449() { recurse448() }
func recurse450() { recurse449() }
func recurse451() { recurse450() }
func recurse452() { recurse451() }
func recurse453() { recurse452() }
func recurse454() { recurse453() }
func recurse455() { recurse454() }
func recurse456() { recurse455() }
func recurse457() { recurse456() }
func recurse458() { recurse457() }
func recurse459() { recurse458() }
func recurse460() { recurse459() }
func recurse461() { recurse460() }
func recurse462() { recurse461() }
func recurse463() { recurse462() }
func recurse464() { recurse463() }
func recurse465() { recurse464() }
func recurse466() { recurse465() }
func recurse467() { recurse466() }
func recurse468() { recurse467() }
func recurse469() { recurse468() }
func recurse470() { recurse469() }
func recurse471() { recurse470() }
func recurse472() { recurse471() }
func recurse473() { recurse472() }
func recurse474() { recurse473() }
func recurse475() { recurse474() }
func recurse476() { recurse475() }
func recurse477() { recurse476() }
func recurse478() { recurse477() }
func recurse479() { recurse478() }
func recurse480() { recurse479() }
func recurse481() { recurse480() }
func recurse482() { recurse481() }
func recurse483() { recurse482() }
func recurse484() { recurse483() }
func recurse485() { recurse484() }
func recurse486() { recurse485() }
func recurse487() { recurse486() }
func recurse488() { recurse487() }
func recurse489() { recurse488() }
func recurse490() { recurse489() }
func recurse491() { recurse490() }
func recurse492() { recurse491() }
func recurse493() { recurse492() }
func recurse494() { recurse493() }
func recurse495() { recurse494() }
func recurse496() { recurse495() }
func recurse497() { recurse496() }