-
Notifications
You must be signed in to change notification settings - Fork 47
Fix aarch64-linux memory corruption #151
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
base: master
Are you sure you want to change the base?
Conversation
|
I see that the changes outside of |
|
I'm not entirely sure why this is the issue, static void advance(Env *env) {
if (not_eof(env)) {
(_array__grow((Array *)(&env->state->lookahead), 1,
(sizeof *(&env->state->lookahead)->contents)),
(&env->state->lookahead)->contents[(&env->state->lookahead)->size++] =
(env->lexer->lookahead));
env->lexer->advance(env->lexer, false);
}
}and with your changes it looks like this: static void advance(Env *env) {
if (not_eof(env)) {
int32_t c = env->lexer->lookahead;
(_array__grow((Array *)(&env->state->lookahead), 1,
(sizeof *(&env->state->lookahead)->contents)),
(&env->state->lookahead)->contents[(&env->state->lookahead)->size++] =
(c));
env->lexer->advance(env->lexer, false);
}
}The order of evaluation for comma separated expressions should be well defined in the C standard, so I'm not sure why we're seeing different behavior only on aarch64. Maybe we have a misbehaving compiler optimization? Regardless, I'm not able to test locally, but if this solves the issue nice work!
These other changes are just because you've generated with a different (newer) version of the tree-sitter CLI than the one that was committed. This generation introduces some breaking changes, which should happen but don't need to in this PR. You should be able to keep the changes to |
Change-Id: Ieb0ebae8376b0e45ebce88215e0cf5436a6a6964
378ba18 to
6f6485f
Compare
|
Thanks @WillLillis, I have now removed the extraneous changes. I agree that this isn't quite a satisfying resolution, but I'm hoping that someone with deeper knowledge of the compiler optimizations might have an idea. In the mean time, this at least lets myself and others continue using |
|
Not super sure what's going on in CI but I don't think it's anything you've done. I'll try to take a look sometime this week. Thanks again for the patch! 🙂 |
|
I unfortunately don't have the permissions on this repo to push this through right now. In the meantime, there's a fork of the repo under tree-sitter-grammars here with the change merged. |
Actually, it's well defined that the order is unspecified. According to the C11 standart:
The same applies for other versions of the C and C++: see https://en.cppreference.com/w/cpp/language/eval_order.html So the compiler on aarch64 probably chooses a different evaluation order, whether intentionally or not. |
|
The issue here is likely a GCC optimizer bug like the one observed in tree-sitter/py-tree-sitter#330. If you want a deep dive into it, you can compile with In any case, this is something we should fix in core by not relying on the comma operation order in the macro. |
|
I'm seeing this issue (at least, I'm pretty sure it's this issue) on arm64 linux, in helix, but not when running I'm the person who rewrote the scanner in C, here, so this bug is probably my fault. Hey, it was for a good cause, right? Speed, portability, simplicity, easy compilation, preventing people from using incredibly slow C++ features... Aaaanyway, @skewb1k and @WillLillis, you two had a little miscommunication. @WillLillis was talking about the comma operator adding a sequence point, but @skewb1k the part of the C spec you linked to was about function arguments (the commas between function arguments don't count as uses of the comma operator). That being the case, I'm not actually sure why this PR fixes the problem... I'd be inclined to change the |
This is an attempt to fix the memory corruption seen on aarch64-linux (in issue 144). On aarch64-linux,
tree-sitter testwould crash, whiletree-sitter test --debug-buildwould pass (except for one test,varsym: error: carrow:, which would fail no matter what, but with a failure seemingly unrelated to the memory corruption). With this change,tree-sitter testpasses all tests butvarsym: error: carrow:and does not exhibit any crashes.Claude helped me track down that the discrepancy between
--debug-buildand not is that--debug-builduses lower optimization flags--O0and-O1are fine, but-O2causes the crash. Claude then identified the change toscanner.cas a potential fix (the remainder of the diff is generated bytree-sitter generate --build). I can't say I fully understand it, but seemingly at higher optimization levels,PEEKmight be incremented simultaneously witharray_pushleading to out-of-bounds memory access?