Skip to content

MultiSegmentArena: preferred segment is not part of the arena #606

@vigliag

Description

@vigliag

Hi. We noticed, after updating to the latest go-capnp version (v3.1.0-alpha.1), that we have some test code triggering a "new struct: preferred segment is not part of the arena" error.

Some (very simplified) code that reproduces the issue is:

struct KV {
    key @0 :Int32;
    value @1 :Data;
}
func TestMultiSegment(t *testing.T) {
	_, seg, err := capnp.NewMessage(capnp.MultiSegment(nil))
	if err != nil {
		t.Fatal(err)
	}
	for i := 0; i < 100; i++ {
		kv, err := NewKV(seg)
		if err != nil {
			t.Fatalf("NewKV(%d): %v", i, err)
		}
		kv.SetKey(int32(i))
		err = kv.SetValue(bytes.Repeat([]byte{byte(i)}, 1024)) // large enough to fill the current segment
		if err != nil {
			t.Fatalf("SetValue(%d): %v", i, err)
		}
                // in a real application, KV would be set to some field of a root message
	}
}

which results in

NewKV(5): new struct: preferred segment is not part of the arena

I think the issue might be here:

if &msa.segs[i] == seg {

We keep passing in the same segment pointer, however the MultiSegmentArena compares it to the address of the segments in the msa.segs slice, whose underlying array can however be reallocated in the meantime (which is why the error only happens on the 6th iteration).

If my understanding is correct, and the issue is with MultiSegmentArena and not with the way we are using the library, a solution would be turning that slice of segment to a slice of pointers to segments. I'm happy to open a PR in that case.

Thanks in advance!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions