Closed eric-j-ason closed 8 months ago
It was just pointed out to me that OpenWrt, where I am running this, doesn't use the latest version.
What architecture does this happen on? I cannot reproduce it on x86/64
Edit: can reproduce on MIPS, will investigate.
I see you could reproduce it on MIPS. I'm relieved to hear that.
My architecture is armv7l, according to uname -m
.
I'm running the version that comes with OpenWrt, which would be c7d84aae09691a99ae3db427c0b2463732ef84f4.
Turns out this is the same issue as #165 which has already been addressed in https://github.com/jow-/ucode/commit/08c2ae23b5dd2deb92f5270ae4fb2094ebfc8a9e
I'll take care of pushing a package update to OpenWrt asap.
Problem is/was that the long
difference of two pointer addresses was stored into an int8_t
variable which could truncate the result in such a way that the actual memory address difference was turned into 0
, leading to false equality result.
Since the actual memory addresses depend on the surrounding activity (how much heap memory was allocated and freed etc.) you get the seemingly unpredictable behavior.
Great! I look forward to pulling in the new version through OpenWrt.
Looking at the fix, I have a question.
Is delta
, an int
, guaranteed to be large enough to hold the difference between two values of type intptr_t
?
In any case, I think lines 2041-2046 can be replaced by a a simple expression.
https://github.com/jow-/ucode/blob/07c03173d4e6a30953f92fa88ed29b0b956c9106/types.c#L2041-L2046
Like so:
delta = ((uintptr_t)v2 > (uintptr_t)v1) - ((uintptr_t)v2 < (uintptr_t)v1)
That way, delta
also needs not be larger than an int8_t
.
delta
is also used to store the int
return value of strcmp()
in the string compare case, so it is better to keep it int
wide.
Never mind! I conflated things. There is no pointer difference being stored in delta
since the fix.
(Well, I do think that it would be nice to calculate the value as just one expression, as opposed to doing explicit if
statements, but it's not necessary for correct behaviour.)
I'll take care of pushing a package update to OpenWrt asap.
I see you have done it. Thanks!
Will this be taken up by the openwrt-23.05 branch and perhaps included in a 23.05.1 release? I don't know what the development strategy for OpenWrt is like, but I would say that this fix is essential to include wherever ucode is used.
Yes it will be picked into the 23.05 branch soon and be part of the 23.05.1 service release.
Running the code below yields an exit status of zero when running with tracing, but non-zero when running without tracing. In the trace, one can find the equality operation quoted above. Exciting!
Funnily, the smallest example code I can produce is over 100 lines long. It's ability to reproduce the bug depends on such things as what happens in functions that are never called, how many lines of whitespace there are, how long variable names are, and sometimes what characters they contain. Try removing or changing something seemingly irrelevant, and you'll see (probably)!