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

cmd/cgo: passing Go pointer to C must pin pointer for lifetime of call #6397

Closed
gopherbot opened this issue Sep 16, 2013 · 29 comments
Closed
Milestone

Comments

@gopherbot
Copy link

by valyala:

Go tip crashes when running the following simple benchmark -
https://github.com/valyala/ybc/blob/master/bindings/go/ybc/perf_test.go . All stable Go
versions (1.0 and 1.1) don't crash on it.

Steps to reproduce:

git clone http://github.com/valyala/ybc
cd ybc
make go-perftests-bindings

Here is crash report sample:

$ make go-perftests-bindings 
GOMAXPROCS=4 go test -a -tags release -test.bench=".*" ./bindings/go/ybc
PASS
BenchmarkCache_GetHit_1-4    2000000           583 ns/op
BenchmarkCache_GetHit_2-4   SIGSEGV: segmentation violation
PC=0x4050d3
signal arrived during cgo execution

runtime.cgocall(0x402b20, 0x2ae1f81b9e20)
    /home/avalyalkin/workspace/go/src/pkg/runtime/cgocall.c:149 +0x11b fp=0x2ae1f81b9e08
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_go_get_item_and_value(0xc2100ce000,
0xc21007b120, 0xc2100b4f98, 0xc2101134c0, 0xc21007c4c0)
    _/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:69 +0x31 fp=0x2ae1f81b9e20
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc2100fe9e0,
0xc210105008, 0x5, 0x5, 0xc2100b4f80, ...)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:563 +0x127 fp=0x2ae1f81b9e50
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc2100fe9e0, 0xc210105008,
0x5, 0x5, 0x0, ...)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0xb9 fp=0x2ae1f81b9e98
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ae1e12bc6c0, 0xc2100fe9e0)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x77 fp=0x2ae1f81b9f48
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xde fp=0x2ae1f81b9fa0
runtime.goexit()
    /home/avalyalkin/workspace/go/src/pkg/runtime/proc.c:1386 fp=0x2ae1f81b9fa8
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x43f

goroutine 1 [chan receive]:
testing.(*B).run(0xc210078f00, 0x0, 0x0, 0x0, 0x0, ...)
    /home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:171 +0x63
testing.RunBenchmarks(0x58b298, 0x8a01a0, 0x1e, 0x1e)
    /home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:303 +0x586
testing.Main(0x58b298, 0x8a0c00, 0x2e, 0x2e, 0x8a01a0, ...)
    /home/avalyalkin/workspace/go/src/pkg/testing/testing.go:409 +0x1c7
main.main()
    _/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_testmain.go:197 +0x9c

goroutine 3 [syscall]:
runtime.goexit()
    /home/avalyalkin/workspace/go/src/pkg/runtime/proc.c:1386

goroutine 56 [semacquire]:
sync.runtime_Semacquire(0xc210105020)
    /home/avalyalkin/workspace/go/src/pkg/runtime/sema.goc:199 +0x30
sync.(*WaitGroup).Wait(0xc2100fefc0)
    /home/avalyalkin/workspace/go/src/pkg/sync/waitgroup.go:127 +0x166
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark(0x527a00, 0x2ae1e1308ed0,
0xc2100fe6a0, 0x2, 0xc210078f00)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:59 +0x45c
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.benchmarkCache_GetHit(0xc210078f00, 0x2,
0x8ae700)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:117 +0x20d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.BenchmarkCache_GetHit_2(0xc210078f00)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:66 +0x35
testing.(*B).runN(0xc210078f00, 0x1e8480)
    /home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:119 +0x94
testing.(*B).launch(0xc210078f00)
    /home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:207 +0x183
created by testing.(*B).run
    /home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:170 +0x40

goroutine 66 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_ybc_item_release(0xc2100d01b0)
    _/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:240 +0x31
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Item).Close(0xc2100cf2c0, 0x0, 0x0)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:797 +0x5d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc2100fe9e0, 0xc210105008,
0x5, 0x5, 0xc210110f20, ...)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:475 +0x122
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ae1e12bc6c0, 0xc2100fe9e0)
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x77
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xde
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
    /home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x43f

rax     0xcbf29da5a32ed089
rbx     0x2ae1f81b9e20
rcx     0x0
rdx     0xc2101134c0
rdi     0xc2100ce000
rsi     0xc21007b120
rbp     0xc21007b120
rsp     0x7fff5565a0e0
r8      0xcbf29da5a32ed089
r9      0xdeaddeaddeaddead
r10     0x0
r11     0x100000001b3
r12     0xc2100b4f98
r13     0x17
r14     0x4
r15     0x10
rip     0x4050d3
rflags  0x10246
cs      0x33
fs      0x0
gs      0x0
exit status 2
FAIL    _/home/avalyalkin/workspace/ybc/bindings/go/ybc 3.544s
make: *** [go-perftests-bindings] Error 1
@ianlancetaylor
Copy link
Contributor

Comment 1:

I don't know what is going on here but we should figure it out before the 1.2 release

Labels changed: added priority-soon, go1.2, removed priority-triage.

@rsc
Copy link
Contributor

rsc commented Sep 17, 2013

Comment 2:

This function is the one that crashed when I ran the test:
func (cache *Cache) GetItem(key []byte) (item *Item, err error) {
    cache.dg.CheckLive()
    item = acquireItem()
    var k C.struct_ybc_key
    initKey(&k, key)
    if C.go_get_item_and_value(cache.ctx(), item.ctx(), &item.value, &k) == 0 {
        releaseItem(item)
        err = ErrCacheMiss
        return
    }
    item.dg.Init()
    return
}
The declaration of var k C.struct_ybc_key is declaring C data as a Go variable; the fact
that &k escapes means that k itself is allocated on the heap, so that &k is just the
heap-allocated pointer. The allocation happens at the line where k is declared. The
calls to initKey, cache.ctx(), and item.ctx() are all simple enough to be inlined, so
the next call after the allocation of k is C.go_get_item_and_value, which ends up in C
code and behaves as if none of its arguments contain pointers (because you cannot in
general pass Go pointers to C anyway). At this point it appears that a garbage
collection happens. There are no references to &k anywhere - the only one is in the
argument to the C function - so the garbage collector reclaims the object k and
incidentally happens to rewrite some of it, so that it is no longer a valid
C.struct_ybc_key. Then the C hash function inside go_get_item_and_value reads the
no-longer-valid struct and crashes.
A workaround here is to make sure &k stays alive. For example you can declare 
var (
   globalb bool
   global interface{}
)
and then put if globalb { global = &k } after the call to C.go_get_item_and_value. It
will never happen but the compiler doesn't see that (today) and the possibility will
keep &k stored on the stack somewhere that the garbage collector will see it. I did this
and now the test passes.
That said, in the long term this kind of thing will keep breaking, especially as the
garbage collector gets better. You should never pass a Go-allocated value to C. If you
need a *struct ybc_key, the only correct way to get one is to call C.malloc and then
C.free it when done. We've made it a little too easy to do the wrong thing here.

Status changed to Unfortunate.

@ianlancetaylor
Copy link
Contributor

Comment 3:

That is odd.  I expect the GC to see arguments to C functions.  After all, they should
be on the Go stack before switching to the g0 stack.  Why doesn't it see them?

@dvyukov
Copy link
Member

dvyukov commented Sep 17, 2013

Comment 4:

I agree with Ian. Looks like compiler bug. The variable is visible alive on source code
level when it's collected.

@gopherbot
Copy link
Author

Comment 5 by valyala:

> The calls to initKey, cache.ctx(), and item.ctx() are all simple enough to be inlined,
so the next call after the allocation of k is C.go_get_item_and_value, which ends up in
C code and behaves as if none of its arguments contain pointers (because you cannot in
general pass Go pointers to C anyway)
A thought &k is more like a C pointer than go pointer, because it has explicit C type -
C.struct_ybc_key.
I'd prefer go compiler putting k on stack rather than allocating it on heap, because:
- stack allocations are cheaper than heap allocations.
- C.ybc_* functions don't remember pointer to k.
Are there technical limits preventing from such a behavior?
How to force go compiler putting C.struct_* variables on stack? The following trick
doesn't help.
var k [1]C.struct_foo
C.func(&k[0])

@gopherbot
Copy link
Author

Comment 6 by valyala:

The following ugly trick can be used as a workaround for the bug:
        var k *C.struct_ybc_key
        var buf [unsafe.Sizeof(*k)]byte
        k = (*C.struct_ybc_key)(unsafe.Pointer(&buf[0]))

@gopherbot
Copy link
Author

Comment 7 by valyala:

The trick from comment #6 doesn't fix the crash :(

@dvyukov
Copy link
Member

dvyukov commented Sep 18, 2013

Comment 8:

Russ, why do you think that alive arguments to C functions should not prevent GC?
Marking this as "New" so that it's not lost.

Status changed to New.

@rsc
Copy link
Contributor

rsc commented Sep 18, 2013

Comment 9:

This isn't a 6c function. It's a gcc function. The garbage collector cannot see what is
going on behind the cgo curtain. The pointer was passed back there, and there is no copy
remaining in the Go program. 
This fundamentally cannot work. You cannot pass Go pointers into C. Use C.malloc to get
a C pointer that you can pass to C. If we had a moving garbage collector (and perhaps we
will some day) you'd have to worry about the allocated Go value changing its pointer.
Even if you were passing a stack pointer, Go stacks may move in the future (probably
sooner than the moving garbage collector).
Fundamentals aside, It is true that C.foo is calling a stub wrapper compiled by 6c. That
frame does not retain the pointer because its argument is recorded (always) as
struct{uint8 x[N];} p, where N is the number of bytes of arguments. It does not declare
any pointers, so the garbage collector does not see any. This is acceptable, because you
should not be passing Go pointers to gcc-compiled code.
I will leave this for Ian to close if I've convinced him.

@eliasnaur
Copy link
Contributor

Comment 10:

I don't see how the problem is fundamental. It might not work that way today, but what's
keeping the 6c compiled stubs from recording its pointers arguments correctly, thus
retaining the memory pointed to from GC for the duration of the call?
In the case of a moving collector, the stubs could record its pointer arguments as
"pinned" so the GC won't move the memory pointed to for the duration of the call.
This might slow down a (moving) collector, but if you can never pass Go pointers to C,
much of Cgo loses its usefulness. In particular, passing C structs from Go to C becomes
awkward and error prone.

@rsc
Copy link
Contributor

rsc commented Sep 20, 2013

Comment 11:

Who says the pointer only lives for the duration of the call? Maybe C is going to record
the pointer in some data structure and use it on the next call? In general this
absolutely cannot work. Passing Go pointers to C is not allowed. Full stop. It's not
much different than writing Go pointers to disk and reading them back and expecting them
to still point to the same data.
The garbage collector only knows the Go heap.

@ianlancetaylor
Copy link
Contributor

Comment 12:

I'm not happy with this.
We ought to be able to pass the address of some object into C code and have the C code
fill in the object.  Obviously plenty of C functions work that way, and they should be
callable from Go.  I agree that it would be wrong for the C function to save the pointer
in any way.  But I assume that is not the issue here (I have not looked at the code).
You are saying that it is never OK to pass a Go pointer to a C function.  I don't think
we have ever said that before, not this strictly.  We have always said that if you pass
a Go pointer to a C function you must keep a copy of that pointer in Go.  But this
function is in effect keeping that pointer--not perhaps in the sense of the compiler,
but after all the pointer is right there in the Go code.
So I think that this code should work and that it would be a mistake to break it. 
Breaking it will make it much harder to write Go interfaces to C libraries.  That would
not be a good thing.  And it will most likely break existing interfaces, though I accept
that one could argue that those interfaces are already broken.
I think I may now understand why this actually fails.  The cgo function is really a C
function compiled by 6c and it has a single struct argument.  6c is recording the type
of the argument, and the GC is using that type.  Thus the GC does not see the pointer
that is in the arguments to the C function.  At least that is my assumption.
If that analysis is correct, then I propose that we add a way for 6c to tell the GC to
conservatively scan the argument information, perhaps via yet another magic comment. 
And we change cgo to emit that comment.  And, yes, if in the future we have a moving
garbage collector such pointers should be pinned.
If we can not do that then I think we must change cgo somehow to reject passing Go
pointers to C code.
This should perhaps be discussed on golang-dev.

@rsc
Copy link
Contributor

rsc commented Sep 20, 2013

Comment 13:

The original docs for cgo were (only) the comments in misc/cgo/gmp/gmp.go,
which still say:
---
Garbage collection is the big problem.  It is fine for the Go world to
have pointers into the C world and to free those pointers when they
are no longer needed.  To help, the Go code can define Go objects
holding the C pointers and use runtime.SetFinalizer on those Go objects.
It is much more difficult for the C world to have pointers into the Go
world, because the Go garbage collector is unaware of the memory
allocated by C.  The most important consideration is not to
constrain future implementations, so the rule is that Go code can
hand a Go pointer to C code but must separately arrange for
Go to hang on to a reference to the pointer until C is done with it.
---
This (old) text implies that we will never have a moving collector. Maybe
that's okay, although that's unfortunate. Even so, what's in this paragraph
still disallows the program in this bug. You cannot allocate something and
pass it to C without keeping a reference to it around in Go too. The fix I
suggested does exactly this.
I wish I had strengthened the constraint here to say that Go pointers may
never be passed directly to C, but I am willing to stand by what I wrote.
Given that, there is much less harm in treating the arguments to a C.foo
function as roots. I'll look into some way to do that.
Russ

@lexprfuncall
Copy link

Comment 14:

I think there are a number of ways to solve this problem which still retain the spirit
of the original text but provide the implementation with more freedom.
On possible solution, used by other systems, is to "buffer" the object being passed to C
into temporary, non-moving (i.e. malloc'ed) storage for the duration of the call.  This
would ensure that the C code can read and write through the pointer without having to
synchronize with the garbage collector.  This can get expensive for large objects but
large objects are usually not-moved even in a moving collector and therefore it is safe
to pass an unbuffered pointer to its contents.
What happens to the buffer, if one is created, can be a policy decision controlled by
the user.  The default behavior would be to copy back and free the buffer.  However, one
could elect to use a different policy, such as allowing the C code to take ownership of
the buffer.
Criticial to any change like this are bit-equality guarnatees for pointers across calls.
 And guarantees about what can be done to pointers in Go structures passed to a call. 
We should be certain not to (explicitly or implicitly) say anything about whether the
pointers are equal and whether a pointer other than what was provided as an argument,
can be dereferenced.  This is important to accomodate a moving collector or a buffering
scheme.

@minux
Copy link
Member

minux commented Sep 20, 2013

Comment 15:

from a user's perspective, i agree with ian in #12.
if I do this:
var t C.struct_XX
C.fill_it(&t)
i certainly don't expect GC collect t when C.fill_it is currently executing.
i agree that if the Go pointer is retained by the C function, the code is badly broken,
but for the common case, GC really shouldn't collect t just as GC won't collect t
while calling a Go function with &t as parameter.
I propose we fix the 6c wrapper to conservatively treat the argument as containing
pointers for Go 1.2 and revisit this problem after the release.

@minux
Copy link
Member

minux commented Sep 20, 2013

Comment 16:

for a concrete example, please see https://golang.org/cl/13786047/.
i really don't think that code is broken (assuming that glibc won't retain the pointer
to hints).
my point is: if our std lib are relying on this, other users very probably also rely on
this,
even from a stability perspective, we shouldn't change it.

@lexprfuncall
Copy link

Comment 17:

I am the author of that change.  That is the only instance of the problem I described
which I have found in the standard library after a few days of testing.  It is based on
a dataflow analysis of variable liveness.

@minux
Copy link
Member

minux commented Sep 20, 2013

Comment 18:

sorry, i just take that code as an example that passing Go pointer to C function that
don't
retain the pointer should work. nothing personally.
in fact, i think cmd/cgo has enough knowledge about the layout the struct that's passing
to the C world that it can generate a correct pointer map for that argument.

@lexprfuncall
Copy link

Comment 19:

No offense taken.  Nevertheless, my observation has been that there are few instances of
pointers being passed to cgo and never reused on the other side of a call.  This is
consistent with the "C code but must separately arrange for Go to hang on to a
reference" quotation above.

@minux
Copy link
Member

minux commented Sep 20, 2013

Comment 20:

as a user, i expect the unfinished call will retain the pointer.
e.g.:
func f() {
  t := S{/* ... */}
  // ....
  blah(&t)
}
do you expect t to be reclaimed when blah is still executing?
i expect the same guarantee should hold when blah is in fact a C function that
won't retain the pointer.

@davecheney
Copy link
Contributor

Comment 21:

> do you expect t to be reclaimed when blah is still executing?
>
> i expect the same guarantee should hold when blah is in fact a C function that
> won't retain the pointer.
I believe this is the crux of the disagreement. As rsc points out, if the function is a
C function, then the guarantee is not present.

@alexbrainman
Copy link
Member

Comment 22:

Russ, don't forget windows. We pass go pointers to windows DLLs left and right. No cgo
involved, so you won't have any control there. Also some windows APIs expect passed
objects to live after the call returned. In these instances, we just keep copy of
pointer in go code to prevent it from GC.
We do that. Our user do that. I don't see how you can take it away.
Alex

@minux
Copy link
Member

minux commented Sep 21, 2013

Comment 23:

ps: i think more and more C libraries are adopting the passing pointer to a (public)
structure
that contains configuration parameters to function to work around C's lack of named
argument
and default parameter values. (getaddrinfo being a notable example of this style)
and in that case, it's quite natural for people to allocate the configuration parameter
structure
(like `hints' in the getaddrinfo case) in Go, and pass its pointer to C, then forget
about that.

@minux
Copy link
Member

minux commented Sep 23, 2013

Comment 24:

Hi @valyala
could you please give https://golang.org/cl/13422048 a try to see if
it could fix the problem?

@rsc
Copy link
Contributor

rsc commented Sep 23, 2013

Comment 25:

I think it's unfortunate that we've ended up here, but the docs we've been shipping are
clear that we support this behavior. It needs to work. I will change the way cgo
generates code so that the pointers are retained, and we will have to keep this in mind
for any future changes that might start moving things in the collector.

Owner changed to @rsc.

Status changed to Accepted.

@gopherbot
Copy link
Author

Comment 26 by valyala:

Unfortunately it didn't fix the problem.
I did the following in order to build patched go:
cd go-sources
put your patch into 1.diff
hg pull && hg up default
hg patch 1.diff
cd src
./all.bash
Then I went to ybc sources and run
make go-perftests-bindings
It has been crashed with:
$ make go-perftests-bindings
GOMAXPROCS=4 go test -a -tags release -test.bench=".*" ./bindings/go/ybc
PASS
BenchmarkCache_GetHit_1-4 5000000       601 ns/op
BenchmarkCache_GetHit_2-4 2000000       544 ns/op
BenchmarkCache_GetHit_4-4 5000000       537 ns/op
BenchmarkCache_GetHit_8-4 --- FAIL: BenchmarkCache_GetHit_8-4
perf_test.go:113: Cannot find item with key=[12345]: [ybc: the item is not
found in the cache]
BenchmarkCache_GetHit_16-4 SIGSEGV: segmentation violation
PC=0x4050d3
signal arrived during cgo execution
runtime.cgocall(0x402b20, 0x2ad4fc78de20)
/home/avalyalkin/workspace/go/src/pkg/runtime/cgocall.c:149 +0x11b
fp=0x2ad4fc78de08
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_go_get_item_and_value(0xc210147000,
0xc2100c9e10, 0xc2100c7a98, 0xc210155fa0, 0xc2100a7400)
_/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:69 +0x31
fp=0x2ad4fc78de20
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100c7a80, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:563 +0xed
fp=0x2ad4fc78de50
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
fp=0x2ad4fc78de98
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
fp=0x2ad4fc78df48
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
fp=0x2ad4fc78dfa0
runtime.goexit()
/home/avalyalkin/workspace/go/src/pkg/runtime/proc.c:1396 fp=0x2ad4fc78dfa8
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 1 [chan receive]:
testing.(*B).run(0xc210078f00, 0x3, 0x2ad4f0982d80, 0x1, 0x1, ...)
/home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:171 +0x4b
testing.RunBenchmarks(0x579838, 0x8921a0, 0x1e, 0x1e)
/home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:303 +0x549
testing.Main(0x579838, 0x892c00, 0x2e, 0x2e, 0x8921a0, ...)
/home/avalyalkin/workspace/go/src/pkg/testing/testing.go:409 +0x1b5
main.main()
_/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_testmain.go:197 +0x9c
goroutine 3 [syscall]:
runtime.goexit()
/home/avalyalkin/workspace/go/src/pkg/runtime/proc.c:1396
goroutine 123 [semacquire]:
sync.runtime_Semacquire(0xc210146020)
/home/avalyalkin/workspace/go/src/pkg/runtime/sema.goc:199 +0x30
sync.(*WaitGroup).Wait(0xc21000a200)
/home/avalyalkin/workspace/go/src/pkg/sync/waitgroup.go:127 +0x14b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark(0x515e00,
0x2ad4f098fed0, 0xc21000a040, 0x10, 0xc210078f00)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:59 +0x3f0
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.benchmarkCache_GetHit(0xc210078f00,
0x10, 0x8a0800)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:117 +0x1c1
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.BenchmarkCache_GetHit_16(0xc210078f00)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:78 +0x35
testing.(*B).runN(0xc210078f00, 0x7a120)
/home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:119 +0x88
testing.(*B).launch(0xc210078f00)
/home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:207 +0x148
created by testing.(*B).run
/home/avalyalkin/workspace/go/src/pkg/testing/benchmark.go:170 +0x2e
goroutine 176 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 175 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 172 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_go_get_item_and_value(0xc210147000,
0xc2100cdea0, 0xc21007ea58, 0xc2101276a0, 0xc200000001)
_/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:69 +0x31
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc21007ea40, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:563 +0xed
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 174 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_GoBytes(0x2ad4fc68f00d,
0xc200000005, 0xc21007ef58, 0xc2101ddd40, 0xc200000001)
_/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:25 +0x3d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Item).Value(0xc21007ef40,
0xc210146008, 0x5, 0x5)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:813 +0x3e
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:472 +0xba
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 177 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc._Cfunc_go_get_item_and_value(0xc210147000,
0xc2100d9240, 0xc2100d6a58, 0xc2100886e0, 0xc200000001)
_/home/avalyalkin/workspace/ybc/bindings/go/ybc/_test/_cgo_defun.c:69 +0x31
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100d6a40, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:563 +0xed
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 173 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100ad980, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:561 +0x5a
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 184 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 183 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 181 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100c5780, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:561 +0x5a
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 180 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 179 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Item).Close(0xc21005cbc0,
0xc2100f5000, 0x5)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:796
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100f5000, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:475 +0xe6
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 178 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc21005c680, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:561 +0x5a
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 185 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 186 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).GetItem(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0xc2100a7180, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:561 +0x5a
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.(*Cache).Get(0xc21000a1c0,
0xc210146008, 0x5, 0x5, 0x0, ...)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/ybc.go:468 +0x7d
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·003(0x2ad4f0943648,
0xc21000a1c0)
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:112 +0x5b
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:49 +0xba
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
goroutine 187 [runnable]:
_/home/avalyalkin/workspace/ybc/bindings/go/ybc.func·001()
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:45
created by _/home/avalyalkin/workspace/ybc/bindings/go/ybc.runBenchmark
/home/avalyalkin/workspace/ybc/bindings/go/ybc/perf_test.go:57 +0x3d3
rax     0xc905f85b416260e0
rbx     0x2ad4fc78de20
rcx     0x1aa050
rdx     0xc210155fa0
rdi     0xc210147000
rsi     0xc2100c9e10
rbp     0xc2100c9e10
rsp     0x2ad4f1d7dde0
r8      0xc905f85b416260e0
r9      0xdeaddeaddeaddead
r10     0xc210155fb0
r11     0x100000001b3
r12     0xc2100c7a98
r13     0x3e
r14     0xc210180c60
r15     0x10
rip     0x4050d3
rflags  0x10217
cs      0x33
fs      0x0
gs      0x0
exit status 2
FAIL _/home/avalyalkin/workspace/ybc/bindings/go/ybc 10.541s
make: *** [go-perftests-bindings] Error 1

@rsc
Copy link
Contributor

rsc commented Sep 24, 2013

Comment 27:

CL https://golang.org/cl/13858043 should take care of this.

Status changed to Started.

@rsc
Copy link
Contributor

rsc commented Sep 24, 2013

Comment 28:

This issue was closed by revision 5639d27.

Status changed to Fixed.

@minux
Copy link
Member

minux commented Sep 25, 2013

Comment 29:

Issue #6470 has been merged into this issue.

@rsc rsc added this to the Go1.2 milestone Apr 14, 2015
@rsc rsc removed the go1.2 label Apr 14, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
@rsc rsc removed their assignment Jun 22, 2022
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

9 participants