Created
August 31, 2012 17:34
-
-
Save ecin/3556241 to your computer and use it in GitHub Desktop.
Dtrace probes in your Golang code
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
package main | |
/* | |
Ping vs Pong: A Gladiatorial Match | |
Two goroutines enter, only one leaves... | |
*/ | |
/* | |
#cgo LDFLAGS: -lprobes -L/usr/local/lib | |
#include "probes.h" | |
*/ | |
import "C" | |
import ( | |
"time" | |
"math/rand" | |
) | |
func ping(c chan int, q chan int) { | |
for ;; { | |
// Prepare a swing | |
time.Sleep(time.Duration(rand.Intn(5)) * time.Second) | |
n := <- c | |
n += 1 | |
if n == 10 { | |
q <- 0 | |
} | |
c <- n | |
// Dtrace spectators: roar for Ping! | |
C.Ping(C.int(n)) | |
} | |
} | |
func pong(c chan int, q chan int) { | |
for ;; { | |
// Charge an attack | |
time.Sleep(time.Duration(rand.Intn(5)) * time.Second) | |
n := <- c | |
n -= 1 | |
if n == 0 { | |
q <- 1 | |
} | |
c <- n | |
// Dtrace spectators: cheer for Pong! | |
C.Pong(C.int(n)) | |
} | |
} | |
func main() { | |
c := make(chan int, 2) | |
q := make(chan int) | |
// Ping and Pong enter the arena | |
go ping(c, q) | |
go pong(c, q) | |
// The match starts! | |
c <- 5 | |
// Wait for victor signal | |
winner := <- q | |
if winner == 0 { | |
println("After a long and arduous battle, Pong falls to its knees, its body a weary mess. Ping wins!") | |
} else { | |
println("Overcome by one too many wounds, Ping rushes to the ground. Pong wins!") | |
} | |
} |
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
/* | |
Compile probes.c as a shared library | |
In Mac OS X (http://www.finkproject.org/doc/porting/shared.php#build-lib): | |
cc -fno-common -c probes.c | |
cc -dynamiclib -install_name /usr/local/lib/libprobes.dylib -o libprobes.dylib probes.o | |
cp libprobes.dylib /usr/local/lib/ | |
*/ | |
#include "probes.h" | |
void Ping(int n) { | |
GOLANG_PING(n); | |
} | |
int Ping_enabled() { | |
return GOLANG_PING_ENABLED(); | |
} | |
void Pong(int n) { | |
GOLANG_PONG(n); | |
} | |
int Pong_enabled() { | |
return GOLANG_PONG_ENABLED(); | |
} |
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
/* | |
Generate probes.h header file with: | |
dtrace -o probes.h -h -s probes.d | |
*/ | |
provider golang { | |
probe ping(int); | |
probe pong(int); | |
}; |
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
/* Header file generated by dtrace */ | |
/* ... */ | |
/* probes.c functions */ | |
void Ping(int); | |
int Ping_enabled(); | |
void Pong(int); | |
int Pong_enabled(); |
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
golang*::Ping: | |
{ | |
printf("Ping hits, counter goes up to #%d!", arg0); | |
} | |
golang*::Pong: | |
{ | |
printf("Pong connects, counter goes down to #%d!", arg0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Demo of static Dtrace probes in Golang. Run with
go run goarena.go
, spectate withsudo dtrace -s spectator.d
.I failed at making Golang's cgo work nicely with a static library, which is why probes.c needs to be compiled as a shared library. Otherwise, dtrace's probe.h file could have been used directly.
Golang bindings for Chris Andrew's libusdt would probably allow more user-friendly dtrace probes in similar programs.