fix(examples): give Streaming_CreateChannel a sample count, not a byte size - #511
Open
nicolas-rabault wants to merge 1 commit into
Open
fix(examples): give Streaming_CreateChannel a sample count, not a byte size#511nicolas-rabault wants to merge 1 commit into
nicolas-rabault wants to merge 1 commit into
Conversation
…e size Streaming_CreateChannel takes ring_buffer_size in samples, it computes end_ring_buffer as ring_buffer + data_size * ring_buffer_size. The laser and galvo services passed sizeof(stream_buf), which is a byte size, so the computed end of the ring landed data_size times too far. Both buffers hold 4096 elements of 4 bytes. Passing 16384 instead of 4096 put end_ring_buffer 65536 bytes from the start of a 16384 byte buffer, so the channel believed it owned 48 KB of memory that belongs to something else, and believed it held 16384 samples instead of 4096. Nothing in streaming.c can catch this. Every bound it checks is derived from end_ring_buffer, so once that is wrong the capacity guard agrees with it. Derive both arguments from the buffer itself so the two cannot drift apart again, and so the element type can change without touching this line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
Streaming_CreateChanneltakesring_buffer_sizein samples:The laser and galvo services passed
sizeof(stream_buf), which is a byte size:ratio_tis{ float }andpos_2d_tis a packed{ uint16_t, uint16_t }, so both are 4 bytes and both channels were told they had 4× the samples they really have.Verified
Computed with the real type definitions:
Each channel believed it owned 48 KB of memory belonging to something else, and that it held 16384 samples instead of 4096.
Why streaming.c cannot save you here
This is worth stating plainly, because it is the reason this is more serious than it looks: every bound
streaming.cchecks is derived fromend_ring_buffer. Once that pointer is wrong, the capacity guard agrees with it and reports the channel as having plenty of room. TheStreaming_PutSamplefix in #508 does not help this case at all — it makes the guard self-consistent, not the declaration correct.Concretely, on
laser.c's non-streaming path:that guard compares against a 16384-sample capacity, so it will happily accept a request that walks 48 KB out of bounds.
The fix
Derive both arguments from the buffer itself:
Two arguments that must agree are now both computed from the same declaration, so they cannot drift, and the element type can change without anyone having to remember this line. For galvo this also replaces the hand-written
2 * sizeof(uint16_t)with the element size it was standing in for — same value,sizeof(pos_2d_t) == 4.Tests
There is no test harness for the product examples, and neither project is built by CI. I built it by hand instead:
That project compiles both
laser.candgalvo.c, so both changes are covered.Not verified: I have no laser/galvo hardware, so I have not observed the corruption or confirmed the fix on a real board. The numbers above are arithmetic on the real type sizes, and the build is real; the runtime behaviour is inferred.
Found while sweeping for the bug in #508
The engine-side bug in #508 was a sample-vs-byte mix-up in
Streaming_PutSample. Sweeping the callers for the same confusion turned these up. The otherStreaming_CreateChannelcallers are correct:pipe.cusesdata_size = 1where the two units coincide, and the motor examples (motor.cpp,dxl.c,controller_motor.c) all pass genuine sample counts.