Skip to content

8360941: [ubsan] MemRegion::end() shows runtime error: applying non-zero offset 8388608 to null pointer #26216

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

MBaesken
Copy link
Member

@MBaesken MBaesken commented Jul 9, 2025

When running HS test
gtest/GTestWrapper.java
with ubsan-enabled binaries on macOS aarch64, the following error is reported (did not see this so far on Linux but there we use gcc and it seems the gcc/ubsan checks are a bit more limited).

test/hotspot/gtest/gc/g1/test_freeRegionList.cpp:37: Failure
Death test: child_G1FreeRegionList_length_()
Result: died but not with expected exit code:
Terminated by signal 6 (core dumped)
Actual msg:

[  DEATH   ] /jdk/src/hotspot/share/memory/memRegion.hpp:66:43: runtime error: applying non-zero offset 8388608 to null pointer
[  DEATH   ]     #0 0x108afd6f4 in MemRegion::end() const+0x84 (libjvm.dylib:arm64+0x16556f4)
[  DEATH   ]     #1 0x1075c68a0 in G1FreeRegionList_length_other_vm_Test::TestBody()+0x380 (libjvm.dylib:arm64+0x11e8a0)
[  DEATH   ]     #2 0x1090f3bb0 in testing::Test::Run()+0xc0 (libjvm.dylib:arm64+0x1c4bbb0)
[  DEATH   ]     #3 0x1090f4d94 in testing::TestInfo::Run()+0x1e4 (libjvm.dylib:arm64+0x1c4cd94)
[  DEATH   ]     #4 0x1090f6754 in testing::TestSuite::Run()+0x43c (libjvm.dylib:arm64+0x1c4e754)
[  DEATH   ]     #5 0x109103ca0 in testing::internal::UnitTestImpl::RunAllTests()+0x48c (libjvm.dylib:arm64+0x1c5bca0)
[  DEATH   ]     #6 0x109103588 in testing::UnitTest::Run()+0x78 (libjvm.dylib:arm64+0x1c5b588)
[  DEATH   ]     #7 0x1074a9ac0 in runUnitTestsInner(int, char**)+0x724 (libjvm.dylib:arm64+0x1ac0)
[  DEATH   ]     #8 0x102dc3f18 in main+0x2c (gtestLauncher:arm64+0x100003f18)
[  DEATH   ]     #9 0x196fea0dc  (<unknown module>)
[  DEATH   ] 
[  DEATH   ] SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /jdk/src/hotspot/share/memory/memRegion.hpp:66:43 in 
[  DEATH   ] 

Seems the test_freeRegionList.cpp uses a special MemRegion starting at nullptr ; but this causes a bit of trouble when adding to start == nullptr .
So far I see this issue just in the gtest, seems other MemRegion objects do not start at nullptr .


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8360941: [ubsan] MemRegion::end() shows runtime error: applying non-zero offset 8388608 to null pointer (Bug - P4)

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/26216/head:pull/26216
$ git checkout pull/26216

Update a local copy of the PR:
$ git checkout pull/26216
$ git pull https://git.openjdk.org/jdk.git pull/26216/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 26216

View PR using the GUI difftool:
$ git pr show -t 26216

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/26216.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 9, 2025

👋 Welcome back mbaesken! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Jul 9, 2025

@MBaesken This change is no longer ready for integration - check the PR body for details.

@openjdk openjdk bot changed the title JDK-8360941: [ubsan] MemRegion::end() shows runtime error: applying non-zero offset 8388608 to null pointer 8360941: [ubsan] MemRegion::end() shows runtime error: applying non-zero offset 8388608 to null pointer Jul 9, 2025
@openjdk openjdk bot added the rfr Pull request is ready for review label Jul 9, 2025
@openjdk
Copy link

openjdk bot commented Jul 9, 2025

@MBaesken The following label will be automatically applied to this pull request:

  • hotspot-runtime

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.

@mlbridge
Copy link

mlbridge bot commented Jul 9, 2025

Copy link
Contributor

@RealLucy RealLucy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks awful to me. But anyway - approved.

This is a perfect example where we destroy the clean look of hotspot code to accommodate odd usage. Wouldn't it be better to code the ugly stuff in the test?

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jul 11, 2025
@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Jul 16, 2025
@MBaesken
Copy link
Member Author

I adjusted the test and took 'some other address than null' .

And removed the cast from the header.

@MBaesken
Copy link
Member Author

Taking 'some other address' than nullptr / 0 as suggested just fails (I worked yesterday with opt build where no failure was seen).
But fastdebug leads to this assert , any ideas ?
Or suggestions for a 'better' address (!= 0) that works ?

#  Internal Error (/openjdk-jdk-dev-linux_aarch64-dbg/jdk/src/hotspot/share/gc/g1/g1HeapRegion.cpp:254), pid=1541642, tid=1541642
#  assert(Universe::on_page_boundary(mr.start()) && Universe::on_page_boundary(mr.end())) failed: invalid space boundaries
#
# Problematic frame:
# V  [libjvm.so+0x110d75c]  G1HeapRegion::G1HeapRegion(unsigned int, G1BlockOffsetTable*, MemRegion, G1CardSetConfiguration*)+0x158
#

---------------  T H R E A D  ---------------

Current thread (0x0000c8cccb63ed40):  JavaThread "main"             [_thread_in_native, id=1541642, stack(0x0000ffffeb8e0000,0x0000ffffebade000) (2040K)]

Stack: [0x0000ffffeb8e0000,0x0000ffffebade000],  sp=0x0000ffffebadc6c0,  free space=2033k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x110d75c]  G1HeapRegion::G1HeapRegion(unsigned int, G1BlockOffsetTable*, MemRegion, G1CardSetConfiguration*)+0x158  (g1HeapRegion.cpp:254)
V  [libjvm.so+0x5a235c]  test_G1FreeRegionList_length_()+0x20c  (test_freeRegionList.cpp:75)
V  [libjvm.so+0x5a29cc]  G1FreeRegionList_length_other_vm_Test::TestBody()+0x32c  (test_freeRegionList.cpp:37)
V  [libjvm.so+0x2075298]  testing::Test::Run()+0xe4  (gtest.cc:2670)
V  [libjvm.so+0x2075424]  testing::TestInfo::Run()+0x170  (gtest.cc:2836)
V  [libjvm.so+0x2075710]  testing::TestSuite::Run()+0x2d0  (gtest.cc:3015)
V  [libjvm.so+0x2081774]  testing::internal::UnitTestImpl::RunAllTests()+0x360  (gtest.cc:5920)
V  [libjvm.so+0x207506c]  testing::UnitTest::Run()+0x7c  (gtest.cc:2670)
V  [libjvm.so+0x45c31c]  runUnitTestsInner(int, char**)+0x3fc  (gtest.h:2317)
C  [gtestLauncher+0x7c0]  main+0x1c  (gtestLauncher.cpp:40)
C  [libc.so.6+0x284c4]
C  [libc.so.6+0x28598]  __libc_start_main+0x98

@MBaesken
Copy link
Member Author

@tschatzl , maybe you have a good suggestion for an address ?
Using 0 / nullptr
MemRegion heap(nullptr, num_regions_in_test * G1HeapRegion::GrainWords);
leads to undefined behaviour because we add to address 0 (and adjusting the HS coding for this is a bit ugly and was not liked).
But the new address used by me in the current commit triggers the assert above .

@kimbarrett
Copy link

kimbarrett commented Jul 17, 2025

Taking 'some other address' than nullptr / 0 as suggested just fails (I worked yesterday with opt build where no failure was seen). But fastdebug leads to this assert , any ideas ? Or suggestions for a 'better' address (!= 0) that works ?

It needs to be at least page-aligned. I'm not finding any other alignment requirement just now, but there might
be a minimum region alignment that is more restrictive than page-aligned that I'm forgetting and haven't found.

So align_up(addr, os::vm_page_size()) may work.

The other likely alignment possibility is G1HeapRegion::GrainWord * BytesPerWord.

I still think allocating the space might be safer. So os::malloc space for one more region than the test calls for, and
align the result up to GrainWord alignment.

@@ -44,7 +44,11 @@ TEST_OTHER_VM(G1FreeRegionList, length) {

// Create a fake heap. It does not need to be valid, as the G1HeapRegion constructor
// does not access it.
MemRegion heap(nullptr, num_regions_in_test * G1HeapRegion::GrainWords);
int val = 1;
HeapWord* ptr = reinterpret_cast<HeapWord*>(&val);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initial value for val doesn't matter, since we're using its address rather than value.
And the cast could be removed by changing the type of val, leading to something like this:

HeapWord val{};
HeapWord* ptr = align_up(&val, os::vm_page_size());

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I adjusted the coding .

@MBaesken
Copy link
Member Author

Hi Kim, should I add you as contributor ?

const size_t szw = num_regions_in_test * G1HeapRegion::GrainWords;
const size_t sz = szw * BytesPerWord;
char* addr = os::reserve_memory(sz, mtTest);
MemRegion heap((HeapWord*)addr, szw);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far as I can tell, there's no guarantee that os::reserve_memory will return an address with any
particular alignment. Since the earlier attempt with unaligned storage failed, it may only be by accident
that this isn't failing as well. We have os::reserve_memory_aligned, or could add an extra region to
the desired size and align up the result.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os::reserve_memory addresses are always regular-page-aligned. But os::reserve_memory_aligned may be better here since I guess the addresses would better have been region-size-aligned, so aligned to G1HeapRegion::GrainWords. That could be larger than system page size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hotspot-runtime [email protected] rfr Pull request is ready for review
Development

Successfully merging this pull request may close these issues.

4 participants