-
-
Notifications
You must be signed in to change notification settings - Fork 51
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
Crash when calculating addressof(self) #79
Comments
The main topic of this issue is the crash of ImHex which should never happen. ImHex 1.33.0 had some stability issues that have been fixed in 1.33.1. You stated that you tested 0.33.1 which looks like a typo but I can't tell which version you meant. To test the latest code download a nightly build from werwolv.net (at the bottom). Although not the main topic, it seems like you also believe that the simplified code you posted should work and it doesn't. In general writing recursive patterns is not easy so I usually create an explicit recursion level variable which is printed along relevant data. I wrote a small example based on your post that limits recursion in two ways. If the size condition is met then no more elements are added to the array and recursion is stopped. If child_len is zero then the array creation is skipped but recursion is allowed to continue. The recursion must first be initialized which usually means writing initial values when recursion equals 1. The Element placed at address 0 has no parent, so we only check the parent data if recursion is greater than one. To effectively stop recursion, the recursive statement must be located inside an if block containing the flow control statements and occur after the control statements. This code is just a suggestion of how recursion can be used. I don't know the details of your usage case so I can't write code that you can just copy, but it should help check possible variations #pragma example 05 04 03 02 01 00 00 00 00 00 00 00 00 00 00 00
#include "std/io.pat"
#include "std/mem.pat"
u32 recursion=0;
struct Element {
recursion +=1;
u8 child_len;
u64 save = $;
if (recursion == 1)
Element children[while(true)];
else if (recursion > 1) {
std::print("Save: {:#x},Len: {},$: {:#x},Recursion: {}",parent.save,parent.child_len,$,recursion);
if ($>parent.save+parent.child_len)
break;
if (child_len==0)
continue;
Element children[while(true)];
}
recursion -=1;
};
Element element@0; it produces the following output on the example input
|
Agreed, it would be nice if
Whoops, yes, it was
I just tried downloading the nightly but that actually claims to be older:
Erm, what? The workaround I posted above seems to work fine, you can run it in ImHex yourself, it reads the tree as
As seen above, it seems to stop fine. In particular, in the case of size zero,
From reading the array type docs, I was under the impression that breaking at the right point while iterating over data was exactly what the loop-sized array syntax was for. Is that not true, and if so, what is it for?
You sound like you know the language better than I do, but the example code you provide seems to be (a) very complicated, and (b) buggy, or at least doing something different than I want: when I run it on my example data I get back a different structure than the one my code produces, though I haven't dug into why. (Possibly worth noting to clarify in case you got confused: the |
Hm, it seems like my original crash is likely a symptom of a more general problem with referencing (currently) unknown variables/fields inside of a loop-sized array expression; the following even-more-minimized example also reliably crashes ImHex 1.33.1:
Interestingly, I also just thought to try it on https://web.imhex.werwolv.net/ and that actually shows a reasonable error message, though I also see some weirdly varying binary-ish garbage in the output. |
well from my poking around in gdb & valgrind it seems like the cause is the errors location (as in where it occurred) being partially allocated, causing a use after free crash. valgrind reports the location being free'd when a |
@paxcut, why don't you open a PR with the proposed code changes? |
Based on other discussions on discord it seems that |
I have a recursive data structure which contains (among other things) a field for the size of the embedded array; reading that array consists of reading elements from the start address of the array until the index pointer matches the data size. Here’s a minimized example of what seemed like the natural way to achieve this:
However, with the example data
05 01 00 02 00 00
, this reliably crashes in ImHex 0.33.1, and also seems to crash (at least it produces no data) on the current version of pl.werwolv.net.Workaround: use
addressof+sizeof
the previous field, but this looks clunky and is hard to keep track of when there are several fields in play:The text was updated successfully, but these errors were encountered: