 +	EvGoRecv:         {"GoRecv", true, []string{}},
  }
 diff --git a/src/runtime/chan.go b/src/runtime/chan.go
-index 5be18be..4966723 100644
+index 5be18be..b3dd1b0 100644
 --- a/src/runtime/chan.go
 +++ b/src/runtime/chan.go
 @@ -23,6 +23,7 @@ const (

 	// someone woke us up
 	if mysg != gp.waiting {
 		throw("G waiting list is corrupted")
@@ -507,6 +534,7 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
 			// ep points to our own stack or heap, so nothing
 			// special (ala sendDirect) needed here.
 			typedmemmove(c.elemtype, ep, sg.elem)
+			traceGoRecv(sg.eventid, c.id, elem2int(ep))
 		}
 	} else {
 		// Queue is full.  Take the item at the
@@ -526,6 +554,7 @@ func recv(c *hchan, sg *sudog, ep unsafe.Pointer, unlockf func()) {
 		}
 		// copy data from sender to queue

 
 type gcstats struct {
diff --git a/src/runtime/select.go b/src/runtime/select.go
index b6c3fea..15fbcfc 100644
--- a/src/runtime/select.go
+++ b/src/runtime/select.go
@@ -383,6 +383,7 @@ loop:
 			c.recvq.enqueue(sg)
 
 		case caseSend:
+			traceGoSend(sg.eventid, c.id, elem2int(sg.elem))
 			c.sendq.enqueue(sg)
 		}
 	}
@@ -423,6 +424,9 @@ loop:
 				c.sendq.dequeueSudoG(sglist)
 			} else {
 				c.recvq.dequeueSudoG(sglist)
+				if sg != nil {
+					traceGoRecv(sg.eventid, sg.cid, elem2int(k.elem))
+				}
 			}
 		}
 		sgnext = sglist.waitlink
diff --git a/src/runtime/trace.go b/src/runtime/trace.go
index 805c34f..6f1c5ed 100644
--- a/src/runtime/trace.go
