Repository navigation
hal: Update matrix keyboard and lcd components to become 64-bit clean #4744
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that the full 64-bit value reaches
num_digits_baseN(), canm *= basewrap? With%xand a value >= 16^15, I thinkmbecomes 0 and the loop never ends in the RT thread (%olikewise for >= 2^63).And with
%o, a 64-bit value can need 22 digits; is anything clampingcto MAX_ENTRY here, or does the digit loop run pastbuff?Counting by division would avoid the wrap:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good one. Changed.
There are still some "gaps" in the conversion. The floating point conversion uses a "blind" conversion to integer and it hopes to fit into a 64-bit value when it counts the digits. Don't know if it is worth the hassle to fix all the problems in lcd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, the hang is gone. The second half of my question still stands, I think: with
%oand a value >= 2^60,num_digits_baseN()returns 21 or 22, and nothing clampscbeforeout[c] = 0, so it writes pastbuff[MAX_ENTRY + 1]. Would one line after the width calculation be enough? The digit loop already prints*when the value does not fit:On the float conversion, I wondered the same, so I pulled
parse_fmt()into a small userspace harness with ASan and UBSan. The float path is unchanged from master, so none of this comes from your PR, but I think one part is worth fixing anyway, because a plain pin value reaches it:%fwith |value| >= 1e15 (default 4 decimals) givesc> MAX_ENTRY, and thegoto overflowpath then fills*up to the unclampedc, so it writes pastbuff. Same for NaN, where the conversion yields 2^63 on x86.0.0000: the "blind" conversion you mention is UB and comes back 0 here.%.25freads pastpow10[], and%5.9f(precision not smaller than width) writes beforebuff.Would something like this be enough? It keeps the existing overflow path and only feeds it a clamped width:
With both changes the harness is clean on 25 cases (64-bit
%u %x %o %d,%ffrom 3.14 to 1e300, inf, NaN,%.25f,%5.9f,%06.2f), and the normal outputs are unchanged. Values that do not fit now show****instead of corrupting memory or showing0.0000. I am fine with this here or as a separate PR, whichever you prefer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
MAX_ENTRYneeds to encompass the%oformat and thus needs to beceil(64/3) = 22or more.The FP question,... Well, the thing is that the calculation will overflow badly when the value is >= 2^64 because the digit calculation truncates the actual value in a cast from double to rtapi_u64. The most obvious overflow is from
%.21fand beyond because it indexes thepow10[]array out of bounds. So a check onm>= NELEM(pow10)` and go to overflow can trivially prevent that.You are right that there are more things that need to be done. I'm not sure it is worth the effort to do much more in this PR as the real problem has been present for a long time. FWIW, the code should probably use
rtapi_vsnprintfderived code instead.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks,
%ois fine now with MAX_ENTRY 22, the harness agrees.On the new
mcheck: I think thegoto overflowcomes beforecgets a value, or am I missing something? With%.25fand no width,cis still -1, soout[c] = 0writes one byte beforebuff; ASan flags it. Giving it the full width first fixes it in the harness:Agreed on leaving the rest out of this PR, since it is old. For the record, what still shows up in the harness:
%fwith values >= 1e18 and NaN write pastbuffthrough the unclampedcin the overflow path,%5.9fwrites before it, and 1e300, inf and%.20fof 1 print zeros.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good you are looking. Missed that one.
But is is also an argument to spit the printable string format into fractions at load time that are passed to
rtapi_snprintf()part-by-part with the correct argument and the full result constructed that way. It would prevent using the reinvention of the wheel as a square with two sides missing ;-)