Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

util/log: use runtime.CallersFrames instead of runtime.Callers #17770

Closed
tbg opened this issue Aug 20, 2017 · 8 comments · Fixed by #35199
Closed

util/log: use runtime.CallersFrames instead of runtime.Callers #17770

tbg opened this issue Aug 20, 2017 · 8 comments · Fixed by #35199
Labels
C-performance Perf of queries or internals. Solution not expected to change functional behavior. E-easy Easy issue to tackle, requires little or no CockroachDB experience help wanted Help is requested / needed by the one who filed the issue to fix it.

Comments

@tbg
Copy link
Member

tbg commented Aug 20, 2017

http://talks.godoc.org/github.com/davecheney/go-1.9-release-party/presentation.slide#20

[tschottdorf@macts-2 cockroach (node-info)]$ git grep runtime.Caller
pkg/storage/timedmutex.go:                      if pc, _, _, ok := runtime.Caller(2); ok {
pkg/storage/track_raft_protos.go:               if numCallers := runtime.Callers(0, pcs[:]); numCallers == len(pcs) {
pkg/storage/track_raft_protos.go:               frames := runtime.CallersFrames(pcs[:])
pkg/util/caller/resolver.go:// A CallResolver is a helping hand around runtime.Caller() to look up file,
pkg/util/caller/resolver.go:// it's unable to look up its own location via runtime.Caller().
pkg/util/caller/resolver.go:    _, file, _, ok := runtime.Caller(0)
pkg/util/caller/resolver.go:    pc, file, line, ok := runtime.Caller(depth + 1)
pkg/util/caller/resolver.go:                    // "path/filepath" because runtime.Caller always returns unix paths.
pkg/util/caller/resolver_test.go:               // NB: runtime.Caller always returns unix paths.
pkg/util/envutil/env.go:        _, consumer, _, _ := runtime.Caller(depth + 1)
pkg/util/log/clog.go:           if runtime.Callers(2+depth, logging.pcs[:]) == 0 {
pkg/util/log/test_log_scope.go: runtime.Callers(2, pcs[:])
pkg/util/log/test_log_scope.go: frames := runtime.CallersFrames(pcs[:])
pkg/util/smalltrace.go: nCallers := runtime.Callers(skip, pcs[:])
pkg/util/smalltrace.go: frames := runtime.CallersFrames(pcs[:])
@tbg tbg added E-easy Easy issue to tackle, requires little or no CockroachDB experience help wanted Help is requested / needed by the one who filed the issue to fix it. labels Aug 20, 2017
@petermattis
Copy link
Collaborator

We should do this, but I don't think it is urgent as mid-stack inlining was not enabled by default for go1.9.

@knz
Copy link
Contributor

knz commented Aug 22, 2017

I think for performance it would do us good to enable mid-stack inlining in CockroachDB.

@petermattis
Copy link
Collaborator

I have the same intuition about mid-stack inlining, yet when I enabled it I could not measure a performance difference:

I did a quick test of --gcflags=-l=4. It bumped the binary size by 7.5%, but I couldn't measure a performance impact on a read-only workload. Perhaps I did something wrong. I'll take another look at this later.

@petermattis
Copy link
Collaborator

See also golang/go#19348 which mentions that --gcflags=-l=4 is unsupported/untested in go1.9.

@dAdAbird
Copy link

Wanted to make it, but there's nothing to do.

As 1.9 release notes state (https://golang.org/doc/go1.9#callersframes):

Users of runtime.Callers should avoid directly inspecting the resulting PC slice and instead use runtime.CallersFrames to get a complete view of the call stack, or runtime.Caller to get information about a single caller.

I haven't found any direct iteration over PC slice in code. All runtime.Callers PCs is used with runtime.CallersFrames.

Anyway runtime.CallersFrames is not a replacement for runtime.Callers, it's a replacement for pc[i] useing.

@dianasaur323 dianasaur323 added this to the Later milestone Sep 17, 2017
@knz
Copy link
Contributor

knz commented Sep 25, 2017

@dAdAbird thanks for the investigation.
What about the code in pkg/util/log/clog.go where the pc[] array is used directly? I think this needs to be changed.

@dAdAbird
Copy link

@knz yeah, you're right, I didn't notice it.
Just in case, to use runtime.CallersFrames here, logging.pcs should have size 2 in order to keep runtime.skipPleaseUseCallersFrames pc along with the caller's pc. But I don't think it's a big issue.

Also, it worth to look closer at runtime.FuncForPC(pc) calls. For example here:
https://github.com/cockroachdb/cockroach/blob/v1.1-beta.20170921/pkg/storage/timedmutex.go#L62-L66 - if there are some inlined functions, despite the Caller return right "file" and "line" (for inlined func) pc always points to the "physical" frame:

package main

import (
	"fmt"
	"runtime"
)

func a() {
	b()
}

func b() {
	pc, _, line, _ := runtime.Caller(1)
	fmt.Println(line, runtime.FuncForPC(pc).Name())
}

func main() {
	a()
}
# go run -gcflags '-l=4' main.go
9 main.main

#go run  main.go
9 main.a

I'd like to take this issue if nobody works on it.

@knz
Copy link
Contributor

knz commented Sep 26, 2017

Please do! That'd be great.

@knz knz added the C-performance Perf of queries or internals. Solution not expected to change functional behavior. label Apr 27, 2018
@knz knz changed the title use runtime.CallersFrames instead of runtime.Callers util/log: use runtime.CallersFrames instead of runtime.Callers Apr 27, 2018
@petermattis petermattis removed this from the Later milestone Oct 5, 2018
nvanbenschoten added a commit to nvanbenschoten/cockroach that referenced this issue Feb 26, 2019
Fixes cockroachdb#17770.

This commit fixes the last user of `runtime.Callers` that misused
the stdlib function by translating the PC values it returned directly
into symbolic information (see https://golang.org/pkg/runtime/#Callers).
Go's documentation warns that this is a recipe for disaster when mixed
with mid-stack inlining.

The other concern in cockroachdb#17770 was this comment:
cockroachdb#17770 (comment).
This was discussed in golang/go#29582 and
addressed in golang/go@956879d.

An alternative would be to use `runtime.Caller` here, but that would
force an allocation that was hard-earned in cockroachdb#29017. Instead, this commit
avoids any performance hit.

```
name                 old time/op    new time/op    delta
Header-4                267ns ± 1%     268ns ± 0%    ~     (p=0.584 n=10+10)
VDepthWithVModule-4     260ns ± 3%     255ns ± 1%  -1.87%  (p=0.018 n=10+9)

name                 old alloc/op   new alloc/op   delta
Header-4                0.00B          0.00B         ~     (all equal)
VDepthWithVModule-4     0.00B          0.00B         ~     (all equal)

name                 old allocs/op  new allocs/op  delta
Header-4                 0.00           0.00         ~     (all equal)
VDepthWithVModule-4      0.00           0.00         ~     (all equal)
```

Release note: None
craig bot pushed a commit that referenced this issue Feb 26, 2019
35014: kv: introduce new "max outstanding size" setting to txnPipeliner r=nvanbenschoten a=nvanbenschoten

Fixes #32522.

This change creates a new cluster setting called:
```
kv.transaction.write_pipelining_max_outstanding_size
```

It limits the size in bytes that can be dedicated to tracking in-flight
writes that have been pipelined. Once this limit is hit, not more writes
will be pipelined by a transaction until some of the writes are proven
and removed from the outstanding write set.

This change once again illustrates the need for periodic proving of
outstanding writes. We touch upon that in the type definition's comment
and in #35009.

Release note: None

35199: log: fix remaining misuse of runtime.Callers/runtime.FuncForPC r=nvanbenschoten a=nvanbenschoten

Fixes #17770.

This commit fixes the last user of `runtime.Callers` that misused
the stdlib function by translating the PC values it returned directly
into symbolic information (see https://golang.org/pkg/runtime/#Callers) [1].
Go's documentation warns that this is a recipe for disaster when mixed
with mid-stack inlining.

The other concern in #17770 was this comment: #17770 (comment).
This was discussed in golang/go#29582 and addressed in golang/go@956879d.

An alternative would be to use `runtime.Caller` here, but that would
force an allocation that was hard-earned in #29017. Instead, this commit
avoids any performance hit.

```
name                 old time/op    new time/op    delta
Header-4                267ns ± 1%     268ns ± 0%    ~     (p=0.584 n=10+10)
VDepthWithVModule-4     260ns ± 3%     255ns ± 1%  -1.87%  (p=0.018 n=10+9)

name                 old alloc/op   new alloc/op   delta
Header-4                0.00B          0.00B         ~     (all equal)
VDepthWithVModule-4     0.00B          0.00B         ~     (all equal)

name                 old allocs/op  new allocs/op  delta
Header-4                 0.00           0.00         ~     (all equal)
VDepthWithVModule-4      0.00           0.00         ~     (all equal)
```

[1] I went through and verified that this was still correct.

Release note: None

35203: closedts: react faster to config changes r=danhhz a=tbg

This approximately halves the duration of

`make test PKG=./pkg/ccl/changefeedccl TESTS=/sinkless`,

from ~60s to ~30s.

Touches #34455.

Release note: None

Co-authored-by: Nathan VanBenschoten <[email protected]>
Co-authored-by: Tobias Schottdorf <[email protected]>
@craig craig bot closed this as completed in #35199 Feb 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-performance Perf of queries or internals. Solution not expected to change functional behavior. E-easy Easy issue to tackle, requires little or no CockroachDB experience help wanted Help is requested / needed by the one who filed the issue to fix it.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants