猿问

FlatBuffers 的多语言集成问题

问题

当我尝试访问包含从一个客户端流式传输到服务器的消息的缓冲区的一部分(使用创建)时,我panic: runtime error: slice bounds out of range从生成的服务器文件中反复出现崩溃( )。 这个问题只出现在客户端和服务器端集成的时候。自己测试,client和server都使用成功,server没有crash 知道: - 发送和接收是一样的,(排除通信方式的问题) - 之前发送的数据格式正确它被放入'并发送。 是什么原因造成的?flatbuffersflatbuffers
flatbuffers// see the boundary tests below

byte[]
flatbuffersbuffer

问题上下文和详细信息

我有c++ 一个go 使用FlatBuffers. _
客户服务器都有自动边界测试,确认它们各自“正确地”使用flatbuffers它们应该的方式。(即客户端在发送缓冲区之前创建缓冲区,服务器在访问缓冲区之前接收缓冲区)
这些测试有效。我们正在使用FlatBuffers-v1.10.0

我的问题是,当它们一起使用时,服务器在访问缓冲区时 总是出现以下错误:

panic: runtime error: slice bounds out of range  


goroutine 19 [running]:

github.com/google/flatbuffers/go.(*Table).GetVOffsetT(...)

     /home/.../go/github.com/google/flatbuffers/go/table.go:134

github.com/google/flatbuffers/go.(*Table).OffsetT(0x4000045c68, 0x4000000004, 0x4000160008)

     /home/.../go/github.com/google/flatbuffers/go/table.go:16 +0xf0

github.com/PhantomIntelligence/Server/lib/Protocol/Stream.(*StreamedData).Id(0x4000045c68, 0x4000045c68)

     /home/.../go/github.com/PhantomIntelligence/Server/lib/Protocol/Stream/SteamedData.go:30 +0x2c

github.com/PhantomIntelligence/Server/dataAccess/conversion/flatBuffers.ConvertStreamMessage(0x4000015a000, 0xa7c, 0xe00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)

     /home/.../go/github.com/PhantomIntelligence/Server/dataAccess/conversion/flatBuffers/deserialization.go:55 +0x1fc

... // the rest is irrelevant for this question's purpose 

导致崩溃的数据

当服务器尝试访问它以使用它时,崩溃总是发生在服务器接收到的第一个缓冲区上。更具体地说,它总是在尝试访问ContainerData7th 的(0th, 12th or 15th) 时发生Container

知道对于这个用例,我们发送一个带有 16 个容器的StreamedData,每个容器包含 16 个ContainerData


代码详情

请注意,只有结构保留在我的原始实现中。我不能泄露我们处理的数据的性质。因此对象名称可能看起来很奇怪,但结构是相关的部分。

架构编译

客户c++ 在编译期间运行它:

flatc -o lib/ --no-js-exports --no-prefix --scoped-enums --cpp schemas/*.fbs

服务器在编译期间运行它 go 

flatc -o lib/ --no-js-exports --no-prefix --scoped-enums --go schemas/*.fbs

图式

客户端服务器都使用以下模式:

请注意,此摘录不是完整的架构,只是与此问题相关的部分。


慕斯王
浏览 136回答 2
2回答

烙印99

不确定这是否是整个问题,但快速浏览一下convertStreamMessage就会发现一个主要问题:这FlatBufferBuilder是一个超出范围的局部变量,就像您返回指向其正在被破坏的内部数据的原始指针一样。您要么希望确保FlatBufferBuilder发送数据后仍然存在,要么改为用作FlatBufferBuilder::Release()返回值。另请注意,在调试这些问题时,您可以使用 C++ 验证程序(或任何读取数据的代码)在发送数据之前检查数据,这样可以更早地发现此问题。

牧羊人nacy

最后解决我的问题的只是增加客户端中生成器的初始缓冲区大小。似乎当构建器调整大小时,位于初始缓冲区末尾(在动态调整大小之前)旁边的 2 个字节未被使用或丢失了数据。我在客户端使用的测试数据没有提出这个问题,它的有效负载比我们使用的真实数据小一点,所以当测试运行时,没有发生调整大小。
随时随地看视频慕课网APP

相关分类

Go
我要回答