Preventing SIGBUS errors when memmove-ing an unsafe.Pointer to multiple destinations

100 views
Skip to first unread message

Viktor Kojouharov

unread,
Jun 7, 2020, 9:14:41 AM6/7/20
to golang-nuts
Hi,

I'm playing around with the runtime, copying some data behind unsafe.Pointer to a destination whenever a function is invoked. I'm currently doing it with the 'typedmemmove' function from within the runtime. That works for certain code, but panics with "unexpected fault address" - going through sigpanic and SIGBUS - with another piece of code. More specifically, the code panics on the second copy, as the first one is fine. Is the panic because the source pointer has been garbage collected somehow? How would I go about figuring out what the underlying cause is, and depending on that, work to fix it?

Thanks

Viktor Kojouharov

unread,
Jun 7, 2020, 9:15:32 AM6/7/20
to golang-nuts
p.s. should such questions be posted in golang-dev, since it deals with runtime internals?

Michael Jones

unread,
Jun 7, 2020, 9:45:40 AM6/7/20
to Viktor Kojouharov, golang-nuts
Do you mean that you have a problem with the value of the pointer? That is "copying the pointer." This seems impossible.

Attempting to access through a pointer copied via unsafe is (generally) inviting doom, and seems highly possible. The instant the last pointer to that data goes out of scope the address range occupied by the formerly pointed to items is formally inaccessible. Using unsafe to keep a shadow copy of the address and then poking around is quite likely to fail, and even when it does not, it is quite likely to be meaningless. (random data from some other use).

If I misunderstood, please forgive me.

On Sun, Jun 7, 2020 at 6:15 AM Viktor Kojouharov <vkojo...@gmail.com> wrote:
p.s. should such questions be posted in golang-dev, since it deals with runtime internals?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/71d7fb5c-3ef5-4611-b9ce-299f7b90945eo%40googlegroups.com.


--
Michael T. Jones
michae...@gmail.com

Viktor Kojouharov

unread,
Jun 7, 2020, 10:53:57 AM6/7/20
to golang-nuts
The pointer is being copied via typedmemmove, which itself calls memmove, which, according to its documentation, copies bytes from the source to the destination. Not sure why that would be impossible, considering it does work for some code (the source pointer preserves its data)

Not sure what you mean by "copied via unsafe". Also, the source pointer never goes out of scope. It's part of a struct that is passed to the function that calls typedmemmove, and its lifetime is more or less static. So while the destination pointers go out of scope, the source one never does.


On Sunday, June 7, 2020 at 4:45:40 PM UTC+3, Michael Jones wrote:
Do you mean that you have a problem with the value of the pointer? That is "copying the pointer." This seems impossible.

Attempting to access through a pointer copied via unsafe is (generally) inviting doom, and seems highly possible. The instant the last pointer to that data goes out of scope the address range occupied by the formerly pointed to items is formally inaccessible. Using unsafe to keep a shadow copy of the address and then poking around is quite likely to fail, and even when it does not, it is quite likely to be meaningless. (random data from some other use).

If I misunderstood, please forgive me.

On Sun, Jun 7, 2020 at 6:15 AM Viktor Kojouharov <vkojo...@gmail.com> wrote:
p.s. should such questions be posted in golang-dev, since it deals with runtime internals?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golan...@googlegroups.com.

Michael Jones

unread,
Jun 7, 2020, 1:02:21 PM6/7/20
to Viktor Kojouharov, golang-nuts
Thank you. I now officially know that I don’t understand. Sorry. 

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/fa18bf7e-8965-4917-9d81-00a8f43289c3o%40googlegroups.com.

keith....@gmail.com

unread,
Jun 7, 2020, 8:12:18 PM6/7/20
to golang-nuts
Showing us some code would really help. It's hard to understand what you are doing from this brief description. Also, where does the SIGBUS occur? What pc, and what address?

What types are you passing as the first argument to typedmemmove? Where did you get them from?

This is a fine question for golang-dev, but don't expect a whole lot of help - reaching into the runtime to call typedmemmove is very unsupported.

Viktor Kojouharov

unread,
Jun 8, 2020, 1:43:58 PM6/8/20
to golang-nuts
The full code can be seen in this diff:


The just of it is, I've added an extra field to a struct (the chan) of type unsafe.Pointer. The value is then copied (allegedly) to a target pointer in chanrecv using typedmemmove. The types of both pointers are the same, as defined by the chan's elemtype

Ian Lance Taylor

unread,
Jun 8, 2020, 2:41:21 PM6/8/20
to Viktor Kojouharov, golang-nuts
On Mon, Jun 8, 2020 at 10:44 AM Viktor Kojouharov <vkojo...@gmail.com> wrote:
>
> The full code can be seen in this diff:
>
> https://github.com/urandom/go/commit/d10ccdd907dac690bfcb31df1115ce1508775458
>
> The just of it is, I've added an extra field to a struct (the chan) of type unsafe.Pointer. The value is then copied (allegedly) to a target pointer in chanrecv using typedmemmove. The types of both pointers are the same, as defined by the chan's elemtype

I only took a quick look, but it looks like you have added a pointer
field to hchan, and presumably the garbage collector needs to know
about that pointer. If you look at makechan in runtime/chan.go, you
will see that a channel whose element type does not contain any
pointers is allocated in such a way that the garbage collector never
looks at it. That will break with your new pointer, as the collector
can collect the value to which the new pointer points without changing
that pointer.

Ian
> To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/aa037e65-0e2a-47d6-b35c-8e80fc3a8000o%40googlegroups.com.

Viktor Kojouharov

unread,
Jun 10, 2020, 7:14:24 AM6/10/20
to golang-nuts
Thanks Ian. Adding to that allocation to cover the element size did the trick. Out of curiosity, the momery allocated by mallocgc is still tracked by the gc, right?
 A brief look at the code seems to indicate that this is the case, but I don't know how the gc works.

Keith Randall

unread,
Jun 10, 2020, 11:09:50 AM6/10/20
to Viktor Kojouharov, golang-nuts
On Wed, Jun 10, 2020 at 4:15 AM Viktor Kojouharov <vkojo...@gmail.com> wrote:
Thanks Ian. Adding to that allocation to cover the element size did the trick. Out of curiosity, the momery allocated by mallocgc is still tracked by the gc, right?
 A brief look at the code seems to indicate that this is the case, but I don't know how the gc works.

Correct.
 
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/V2abC-HQvYk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/01e4daa4-568d-4d56-9691-66272e908a3do%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages