-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8346714: [ASAN] compressedKlass.cpp reported applying non-zero offset to null pointer #22848
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
Conversation
👋 Welcome back syan! A progress list of the required criteria for merging this PR into |
@sendaoYan This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 7 new commits pushed to the
Please see this link for an up-to-date comparison between the source branch of this pull request and the ➡️ To integrate this PR with the above commit message to the |
@sendaoYan The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
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.
"encoding" is the correct spelling. If you cast _base
and encoding_offset
to uintptr_t
you can do the addition without null check. (Then cast the sum back to address
.)
Thanks for the advice. PR has been updated. |
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 for fixing the issue! This should work.
In general, I still prefer using uintptr_t
because intptr_t
has undefined behavior on overflow. Probably not in this case, here.
Sorry, got it now. The |
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! LGTM.
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.
This looks better than the conditional on _addr. Thanks for fixing these errors.
GHA report 1 failure:
|
+1. Also, instead of casting manually, please use p2u (and if there is none, we should add it like we have a p2i for intptr_t). I am somewhat unenthusiastic about changes like these. We seem to add a lot of casting boilerplate to satisfy UBsan for the sake of cleanliness that only matters on special hardware that treats pointers differently from numeric. Like old-style IBM AS/400s. But if we ever build for that kind of hardware, nothing will work anyway. I am happy to be corrected, though, but I think all our compilers treat NULL as numeric 0, right? |
Casting manually has been replaced as use p2u. |
True, but we can very effectively make the compiler and the reader happy by using |
Okay, but this is just for the sake of the reader, right? Because a cast can be just as invalid as adding to NULL. I worked on hardware that marked pointers as invalid if they resulted from an integer cast. I assume that "don't add to NULL" warnings exist to preserve portability for these platforms. My thought is: since we cannot hope to achieve portability for these platforms anyway, we might just as well allow adding to NULL. Casting feels like just switching off these warnings. Note that even if I convert the whole of CompressedKlassPointers to uintptr_t, we will need a cast at the latest when we use the base as input to mmap. But I agree that UBSAN cleanliness is valuable since most of its warnings are good, and maybe its just simpler to fix these issues than to argue about them. So, I am fine with this patch. |
@@ -96,7 +96,7 @@ void CompressedKlassPointers::sanity_check_after_initialization() { | |||
|
|||
// Check that Klass range is fully engulfed in the encoding range | |||
const address encoding_start = _base; | |||
const address encoding_end = _base + nth_bit(narrow_klass_pointer_bits() + _shift); | |||
const address encoding_end = (address)(p2u(_base) + (uintptr_t)nth_bit(narrow_klass_pointer_bits() + _shift)); |
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.
nth_bit should already give us a 64-bit value, why the second cast?
I see that nth_bit returns an intptr_t - is the sign the problem? We may want to change that to uintptr_t...
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.
Prefer using uintptr_t
because intptr_t
has undefined behavior on overflow. Probably not in this case, here.
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.
It should work without the second cast, but there may be compiler warnings like "warning: implicit conversion changes signedness: 'long' to 'unsigned long' [-Wsign-conversion]".
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.
It should work without the second cast, but there may be compiler warnings like "warning: implicit conversion changes signedness: 'long' to 'unsigned long' [-Wsign-conversion]".
Yes, below example can reproduce the gcc/clang compile warning.
#include <stdio.h>
int main()
{
unsigned long a = 1;
signed long b = 2;
printf("%llu\n", (long long unsigned int)(a + b));
return 0;
}
Undefined behavior is a risk. Compilers currently seem to do what we want, but there's no guarantee. They could optimize the code in a way which breaks it. That would be legal since it is undefined behavior. |
Thank all for the detailed discussion, explanation and reviews. /integrate |
Going to push as commit bffa77b.
Your commit was automatically rebased without conflicts. |
@sendaoYan Pushed as commit bffa77b. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Mailing list message from Andrew Haley on hotspot-dev: On 12/23/24 07:26, Thomas Stuefe wrote:
I don't agree. Adding to NULL is explicitly UB. C++ doesn't have to generate
That's not so. Current C++ compilers can, and some do, correctly generate no code for anything following UB. If you were to convert a pointer to uintptr_t, discover that it fits in an int, convert it to an int, and
No. That is UB.
That's how it feels, sure, but you're moving from UB to implementation-defined behaviour.
Yes. Good.
|
@theRealAph @TheRealMDoerr Thank you for your points! You have convinced me. |
Hi all,
CompressedKlassPointers::sanity_check_after_initialization() src/hotspot/share/oops/compressedKlass.cpp:104:38 reported runtime error: applying non-zero offset 4294967296 to null pointer by clang17 UndefinedBehaviorSanitizer.
The _base initial as nullptr in function CompressedKlassPointers::initialize(address addr, size_t len) shows as below. In C/C++, offsetting a null pointer is undefined behavior. This PR do not change the original logic but eliminate the undefined behaviour in code, the risk is low.
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/22848/head:pull/22848
$ git checkout pull/22848
Update a local copy of the PR:
$ git checkout pull/22848
$ git pull https://git.openjdk.org/jdk.git pull/22848/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 22848
View PR using the GUI difftool:
$ git pr show -t 22848
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/22848.diff
Using Webrev
Link to Webrev Comment