Dynamic instrumentation for runtime verification

I am new to Go. I have been investigating ways to dynamically instrument Go applications. By dynamic, I mean mechanisms like Dyninst, Callgrind, and Intel Pin that instrument the binary without the need of source-code modification. My goal is to collect information about the dynamic behavior of Go applications with respect to channels and goroutines. I want to dynamically verify (check liveness and safety) of channels and detect deadlocks (and maybe races) that the Go built-in detectors could not catch. I found Go profilers, execution tracers and GODEBUG features (all explained here) useless for this purpose as the collected data are limited statistics gathered by sampling. Using “reflection” and “go generate” as explained here or “plugins” to intercept with calls are some options but I am not sure if they serve my purpose.
Is it possible at all to dynamically instrument Go applications to collect dynamic information about :

  • Creating/closing a channel
  • Send/receive to/from a channel
  • Select (guarded choice)?

I am posting this here as I am sure many of you can help me to clear things. Thanks in advance.