-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is actually two separate hacks. Hack 1: gogo is either used to switch to something in the current stack or an entirely separate stack. If we're switching to an existing stack, assume that we're resuming execution at the lowest stack frame with the same symbol as what gogo jumped into. If there's no existing stack frame that matches the gogo target, assume we're switching to an entirely separate stack. One place where this strategy breaks down is that it doesn't work well with recursive functions that switch between goroutines. I suspect that's not a very common pattern in non-adversaial go code, and hope this will work well for most people. Testing: There was already a test around this case, I'm trying out this new strategy to cover more bases than just what's in the demo script. Turns out real go code can jump into more than two functions. Hack 2: A goroutine that returns, when there are no other goroutines, returns into a function called "runtime.goexit.abi0". When magic-trace sees a return into that symbol, it ends the current thread and pretends there's a call to goexit. The goal here is to end the outstanding stack frames and not infer goexit as starting at the last thread end. Testing: I added a perf test around the complete golang exit sequence.
- Loading branch information
Showing
5 changed files
with
191 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
open! Core | ||
|
||
let%expect_test "golang exit sequence" = | ||
Perf_script.run ~trace_mode:Userspace "golang_exit.perf"; | ||
[%expect | ||
{| | ||
3268985/3268994 3444853.363323631: call 439440 runtime.execute+0x80 => 4365e0 runtime.casgstatus+0x0 | ||
3268985/3268994 3444853.363323637: return 4368ab runtime.casgstatus+0x2cb => 439445 runtime.execute+0x85 | ||
-> 1ns BEGIN runtime.casgstatus | ||
3268985/3268994 3444853.363323641: call 4394e9 runtime.execute+0x129 => 45e100 runtime.gogo.abi0+0x0 | ||
-> 7ns END runtime.casgstatus | ||
3268985/3268994 3444853.363323642: jmp 45e10c runtime.gogo.abi0+0xc => 45d320 gogo+0x0 | ||
-> 11ns BEGIN runtime.gogo.abi0 | ||
3268985/3268994 3444853.363323643: jmp 45d35e gogo+0x3e => 434b36 runtime.gopark+0xd6 | ||
-> 12ns END runtime.gogo.abi0 | ||
-> 12ns BEGIN gogo | ||
-> 0ns BEGIN runtime.execute [inferred start time] | ||
-> 13ns END gogo | ||
-> 13ns END runtime.execute | ||
3268985/3268994 3444853.363323644: return 434b40 runtime.gopark+0xe0 => 4061cc runtime.chanrecv+0x56c | ||
-> 13ns BEGIN runtime.gopark | ||
3268985/3268994 3444853.363323648: call 406280 runtime.chanrecv+0x620 => 434f60 runtime.releaseSudog+0x0 | ||
-> 14ns END runtime.gopark | ||
3268985/3268994 3444853.363323652: return 4350ce runtime.releaseSudog+0x16e => 406285 runtime.chanrecv+0x625 | ||
-> 18ns BEGIN runtime.releaseSudog | ||
3268985/3268994 3444853.363323653: return 40629e runtime.chanrecv+0x63e => 405c38 runtime.chanrecv1+0x18 | ||
-> 22ns END runtime.releaseSudog | ||
3268985/3268994 3444853.363323654: return 405c41 runtime.chanrecv1+0x21 => 507a72 main.(*sequencer).GetExitCode+0x92 | ||
-> 23ns END runtime.chanrecv | ||
3268985/3268994 3444853.363323655: return 507a80 main.(*sequencer).GetExitCode+0xa0 => 508f0f main.main+0x14f | ||
-> 24ns END runtime.chanrecv1 | ||
3268985/3268994 3444853.363323656: call 508f0f main.main+0x14f => 49d300 os.Exit+0x0 | ||
-> 25ns END main.(*sequencer).GetExitCode | ||
3268985/3268994 3444853.363323657: call 49d320 os.Exit+0x20 => 495f40 internal/testlog.PanicOnExit0+0x0 | ||
-> 26ns BEGIN os.Exit | ||
3268985/3268994 3444853.363323659: call 495fd9 internal/testlog.PanicOnExit0+0x99 => 496020 internal/testlog.PanicOnExit0.func1+0x0 | ||
-> 27ns BEGIN internal/testlog.PanicOnExit0 | ||
3268985/3268994 3444853.363323660: call 496041 internal/testlog.PanicOnExit0.func1+0x21 => 465d20 sync.(*Mutex).Unlock+0x0 | ||
-> 29ns BEGIN internal/testlog.PanicOnExit0.func1 | ||
3268985/3268994 3444853.363323662: return 465d52 sync.(*Mutex).Unlock+0x32 => 496046 internal/testlog.PanicOnExit0.func1+0x26 | ||
-> 30ns BEGIN sync.(*Mutex).Unlock | ||
3268985/3268994 3444853.363323663: return 49604f internal/testlog.PanicOnExit0.func1+0x2f => 495fdb internal/testlog.PanicOnExit0+0x9b | ||
-> 32ns END sync.(*Mutex).Unlock | ||
3268985/3268994 3444853.363323664: return 495fe9 internal/testlog.PanicOnExit0+0xa9 => 49d325 os.Exit+0x25 | ||
-> 33ns END internal/testlog.PanicOnExit0.func1 | ||
3268985/3268994 3444853.363323665: call 49d329 os.Exit+0x29 => 45bc20 os.runtime_beforeExit+0x0 | ||
-> 34ns END internal/testlog.PanicOnExit0 | ||
3268985/3268994 3444853.363323666: return 45bc20 os.runtime_beforeExit+0x0 => 49d32e os.Exit+0x2e | ||
-> 35ns BEGIN os.runtime_beforeExit | ||
3268985/3268994 3444853.363323667: call 49d333 os.Exit+0x33 => 45c300 syscall.Exit+0x0 | ||
-> 36ns END os.runtime_beforeExit | ||
3268985/3268994 3444853.363323668: call 45c311 syscall.Exit+0x11 => 4619e0 runtime.exit.abi0+0x0 | ||
-> 37ns BEGIN syscall.Exit | ||
3268985/3268994 3444853.363323669: tr end syscall 4619e9 runtime.exit.abi0+0x9 => 0 [unknown] | ||
-> 38ns BEGIN runtime.exit.abi0 | ||
END | ||
-> 13ns BEGIN main.main [inferred start time] | ||
-> 13ns BEGIN main.(*sequencer).GetExitCode [inferred start time] | ||
-> 13ns BEGIN runtime.chanrecv1 [inferred start time] | ||
-> 13ns BEGIN runtime.chanrecv [inferred start time] | ||
-> 39ns BEGIN [syscall] | ||
-> 39ns END [syscall] | ||
-> 39ns END runtime.exit.abi0 | ||
-> 39ns END syscall.Exit | ||
-> 39ns END os.Exit | ||
-> 39ns END main.main |}] | ||
;; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
(* intentionally left blank *) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
3268985/3268994 3444853.363323630: jmp 439421 runtime.execute+0x61 => 43942c runtime.execute+0x6c | ||
3268985/3268994 3444853.363323631: call 439440 runtime.execute+0x80 => 4365e0 runtime.casgstatus+0x0 | ||
3268985/3268994 3444853.363323632: jcc 43660a runtime.casgstatus+0x2a => 43664e runtime.casgstatus+0x6e | ||
3268985/3268994 3444853.363323633: jmp 436652 runtime.casgstatus+0x72 => 43666a runtime.casgstatus+0x8a | ||
3268985/3268994 3444853.363323634: jcc 436683 runtime.casgstatus+0xa3 => 43672a runtime.casgstatus+0x14a | ||
3268985/3268994 3444853.363323635: jcc 43672d runtime.casgstatus+0x14d => 436751 runtime.casgstatus+0x171 | ||
3268985/3268994 3444853.363323636: jcc 436758 runtime.casgstatus+0x178 => 4368a2 runtime.casgstatus+0x2c2 | ||
3268985/3268994 3444853.363323637: return 4368ab runtime.casgstatus+0x2cb => 439445 runtime.execute+0x85 | ||
3268985/3268994 3444853.363323638: jmp 439479 runtime.execute+0xb9 => 43948e runtime.execute+0xce | ||
3268985/3268994 3444853.363323639: jcc 4394a6 runtime.execute+0xe6 => 4394b2 runtime.execute+0xf2 | ||
3268985/3268994 3444853.363323640: jcc 4394b9 runtime.execute+0xf9 => 4394e1 runtime.execute+0x121 | ||
3268985/3268994 3444853.363323641: call 4394e9 runtime.execute+0x129 => 45e100 runtime.gogo.abi0+0x0 | ||
3268985/3268994 3444853.363323642: jmp 45e10c runtime.gogo.abi0+0xc => 45d320 gogo+0x0 | ||
3268985/3268994 3444853.363323643: jmp 45d35e gogo+0x3e => 434b36 runtime.gopark+0xd6 | ||
3268985/3268994 3444853.363323644: return 434b40 runtime.gopark+0xe0 => 4061cc runtime.chanrecv+0x56c | ||
3268985/3268994 3444853.363323645: jmp 406201 runtime.chanrecv+0x5a1 => 40620f runtime.chanrecv+0x5af | ||
3268985/3268994 3444853.363323646: jcc 40621d runtime.chanrecv+0x5bd => 40623e runtime.chanrecv+0x5de | ||
3268985/3268994 3444853.363323647: jmp 406262 runtime.chanrecv+0x602 => 40627c runtime.chanrecv+0x61c | ||
3268985/3268994 3444853.363323648: call 406280 runtime.chanrecv+0x620 => 434f60 runtime.releaseSudog+0x0 | ||
3268985/3268994 3444853.363323648: jcc 435007 runtime.releaseSudog+0xa7 => 435012 runtime.releaseSudog+0xb2 | ||
3268985/3268994 3444853.363323649: jcc 43502e runtime.releaseSudog+0xce => 435079 runtime.releaseSudog+0x119 | ||
3268985/3268994 3444853.363323650: jmp 435095 runtime.releaseSudog+0x135 => 43509c runtime.releaseSudog+0x13c | ||
3268985/3268994 3444853.363323651: jcc 4350bb runtime.releaseSudog+0x15b => 4350c5 runtime.releaseSudog+0x165 | ||
3268985/3268994 3444853.363323652: return 4350ce runtime.releaseSudog+0x16e => 406285 runtime.chanrecv+0x625 | ||
3268985/3268994 3444853.363323653: return 40629e runtime.chanrecv+0x63e => 405c38 runtime.chanrecv1+0x18 | ||
3268985/3268994 3444853.363323654: return 405c41 runtime.chanrecv1+0x21 => 507a72 main.(*sequencer).GetExitCode+0x92 | ||
3268985/3268994 3444853.363323655: return 507a80 main.(*sequencer).GetExitCode+0xa0 => 508f0f main.main+0x14f | ||
3268985/3268994 3444853.363323656: call 508f0f main.main+0x14f => 49d300 os.Exit+0x0 | ||
3268985/3268994 3444853.363323657: call 49d320 os.Exit+0x20 => 495f40 internal/testlog.PanicOnExit0+0x0 | ||
3268985/3268994 3444853.363323658: jcc 495f86 internal/testlog.PanicOnExit0+0x46 => 495f94 internal/testlog.PanicOnExit0+0x54 | ||
3268985/3268994 3444853.363323659: call 495fd9 internal/testlog.PanicOnExit0+0x99 => 496020 internal/testlog.PanicOnExit0.func1+0x0 | ||
3268985/3268994 3444853.363323660: call 496041 internal/testlog.PanicOnExit0.func1+0x21 => 465d20 sync.(*Mutex).Unlock+0x0 | ||
3268985/3268994 3444853.363323661: jcc 465d42 sync.(*Mutex).Unlock+0x22 => 465d49 sync.(*Mutex).Unlock+0x29 | ||
3268985/3268994 3444853.363323662: return 465d52 sync.(*Mutex).Unlock+0x32 => 496046 internal/testlog.PanicOnExit0.func1+0x26 | ||
3268985/3268994 3444853.363323663: return 49604f internal/testlog.PanicOnExit0.func1+0x2f => 495fdb internal/testlog.PanicOnExit0+0x9b | ||
3268985/3268994 3444853.363323664: return 495fe9 internal/testlog.PanicOnExit0+0xa9 => 49d325 os.Exit+0x25 | ||
3268985/3268994 3444853.363323665: call 49d329 os.Exit+0x29 => 45bc20 os.runtime_beforeExit+0x0 | ||
3268985/3268994 3444853.363323666: return 45bc20 os.runtime_beforeExit+0x0 => 49d32e os.Exit+0x2e | ||
3268985/3268994 3444853.363323667: call 49d333 os.Exit+0x33 => 45c300 syscall.Exit+0x0 | ||
3268985/3268994 3444853.363323668: call 45c311 syscall.Exit+0x11 => 4619e0 runtime.exit.abi0+0x0 | ||
3268985/3268994 3444853.363323669: tr end syscall 4619e9 runtime.exit.abi0+0x9 => 0 [unknown] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters