• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2016 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//go:build unix
6// +build unix
7
8package main
9
10// Test that we can collect a lot of colliding profiling signals from
11// an external C thread. This used to fail when built with the race
12// detector, because a call of the predeclared function copy was
13// turned into a call to runtime.slicecopy, which is not marked nosplit.
14
15/*
16#include <signal.h>
17#include <stdint.h>
18#include <pthread.h>
19#include <sched.h>
20
21struct cgoTracebackArg {
22	uintptr_t  context;
23	uintptr_t  sigContext;
24	uintptr_t* buf;
25	uintptr_t  max;
26};
27
28static int raceprofCount;
29
30// We want a bunch of different profile stacks that collide in the
31// hash table maintained in runtime/cpuprof.go. This code knows the
32// size of the hash table (1 << 10) and knows that the hash function
33// is simply multiplicative.
34void raceprofTraceback(void* parg) {
35	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
36	raceprofCount++;
37	arg->buf[0] = raceprofCount * (1 << 10);
38	arg->buf[1] = 0;
39}
40
41static void* raceprofThread(void* p) {
42	int i;
43
44	for (i = 0; i < 100; i++) {
45		pthread_kill(pthread_self(), SIGPROF);
46		sched_yield();
47	}
48	return 0;
49}
50
51void runRaceprofThread() {
52	pthread_t tid;
53	pthread_create(&tid, 0, raceprofThread, 0);
54	pthread_join(tid, 0);
55}
56*/
57import "C"
58
59import (
60	"bytes"
61	"fmt"
62	"runtime"
63	"runtime/pprof"
64	"unsafe"
65)
66
67func init() {
68	register("CgoRaceprof", CgoRaceprof)
69}
70
71func CgoRaceprof() {
72	runtime.SetCgoTraceback(0, unsafe.Pointer(C.raceprofTraceback), nil, nil)
73
74	var buf bytes.Buffer
75	pprof.StartCPUProfile(&buf)
76
77	C.runRaceprofThread()
78	fmt.Println("OK")
79}
80