Skip to content

Commit 7adbd98

Browse files
[GR-70641] Use LibC.free(...) when freeing native memory that was allocated by the libc or other native code.
PullRequest: graal/22329
2 parents f1794b7 + 893ad58 commit 7adbd98

File tree

7 files changed

+44
-29
lines changed

7 files changed

+44
-29
lines changed

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/PosixProcessPropertiesSupport.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import com.oracle.svm.core.BaseProcessPropertiesSupport;
4242
import com.oracle.svm.core.c.locale.LocaleSupport;
4343
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
44-
import com.oracle.svm.core.memory.UntrackedNullableNativeMemory;
44+
import com.oracle.svm.core.headers.LibC;
4545
import com.oracle.svm.core.posix.headers.Dlfcn;
4646
import com.oracle.svm.core.posix.headers.Signal;
4747
import com.oracle.svm.core.posix.headers.Stdlib;
@@ -105,7 +105,7 @@ public String getObjectFile(PointerBase symbolAddress) {
105105
try {
106106
return CTypeConversion.toJavaString(realpath);
107107
} finally {
108-
UntrackedNullableNativeMemory.free(realpath);
108+
LibC.free(realpath);
109109
}
110110
}
111111

@@ -165,11 +165,13 @@ protected static String realpath(String path) {
165165
if (realpath.isNull()) {
166166
/* Failure to find a real path. */
167167
return null;
168-
} else {
168+
}
169+
170+
try {
169171
/* Success */
170-
String result = CTypeConversion.toJavaString(realpath);
171-
UntrackedNullableNativeMemory.free(realpath);
172-
return result;
172+
return CTypeConversion.toJavaString(realpath);
173+
} finally {
174+
LibC.free(realpath);
173175
}
174176
}
175177
}

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/darwin/DarwinSystemPropertiesSupport.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.posix.darwin;
2626

27-
import jdk.graal.compiler.word.Word;
2827
import org.graalvm.nativeimage.ImageSingletons;
2928
import org.graalvm.nativeimage.Platform;
3029
import org.graalvm.nativeimage.c.function.CLibrary;
@@ -37,14 +36,16 @@
3736
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
3837
import com.oracle.svm.core.feature.InternalFeature;
3938
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
39+
import com.oracle.svm.core.headers.LibC;
4040
import com.oracle.svm.core.jdk.SystemPropertiesSupport;
41-
import com.oracle.svm.core.memory.UntrackedNullableNativeMemory;
4241
import com.oracle.svm.core.posix.PosixSystemPropertiesSupport;
4342
import com.oracle.svm.core.posix.headers.Limits;
4443
import com.oracle.svm.core.posix.headers.Stdlib;
4544
import com.oracle.svm.core.posix.headers.Unistd;
4645
import com.oracle.svm.core.posix.headers.darwin.Foundation;
4746

47+
import jdk.graal.compiler.word.Word;
48+
4849
@CLibrary(value = "darwin", requireStatic = true)
4950
public class DarwinSystemPropertiesSupport extends PosixSystemPropertiesSupport {
5051

@@ -105,7 +106,7 @@ protected String osVersionValue() {
105106
CCharPointer osVersionStr = Foundation.systemVersionPlatform();
106107
if (osVersionStr.isNonNull()) {
107108
osVersionValue = CTypeConversion.toJavaString(osVersionStr);
108-
UntrackedNullableNativeMemory.free(osVersionStr);
109+
LibC.free(osVersionStr);
109110
return osVersionValue;
110111
}
111112
} else {
@@ -120,7 +121,7 @@ protected String osVersionValue() {
120121
CCharPointer osVersionStr = Foundation.systemVersionPlatformFallback();
121122
if (osVersionStr.isNonNull()) {
122123
osVersionValue = CTypeConversion.toJavaString(osVersionStr);
123-
UntrackedNullableNativeMemory.free(osVersionStr);
124+
LibC.free(osVersionStr);
124125
return osVersionValue;
125126
}
126127
return osVersionValue = "Unknown";

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/headers/LibC.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424
*/
2525
package com.oracle.svm.core.headers;
2626

27+
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
28+
2729
import org.graalvm.nativeimage.ImageSingletons;
30+
import org.graalvm.nativeimage.UnmanagedMemory;
2831
import org.graalvm.nativeimage.c.type.CCharPointer;
2932
import org.graalvm.nativeimage.c.type.CCharPointerPointer;
3033
import org.graalvm.word.PointerBase;
@@ -34,6 +37,9 @@
3437
import com.oracle.svm.core.Uninterruptible;
3538
import com.oracle.svm.core.imagelayer.ImageLayerBuildingSupport;
3639
import com.oracle.svm.core.layeredimagesingleton.LayeredImageSingletonSupport;
40+
import com.oracle.svm.core.memory.NativeMemory;
41+
import com.oracle.svm.core.memory.NullableNativeMemory;
42+
import com.oracle.svm.core.memory.UntrackedNullableNativeMemory;
3743
import com.oracle.svm.core.traits.SingletonLayeredInstallationKind;
3844
import com.oracle.svm.core.traits.SingletonTraitKind;
3945

@@ -88,6 +94,17 @@ public static void abort() {
8894
exit(EXIT_CODE_ABORT);
8995
}
9096

97+
/**
98+
* May only be used to free memory that was allocated by the libc or other native code. Do
99+
* <b>NOT</b> use this method when freeing memory that was allocated via internal APIs such as
100+
* {@link NativeMemory}, {@link NullableNativeMemory}, {@link UntrackedNullableNativeMemory}, or
101+
* {@link UnmanagedMemory}.
102+
*/
103+
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
104+
public static void free(PointerBase ptr) {
105+
libc().free(ptr);
106+
}
107+
91108
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
92109
public static UnsignedWord strlen(CCharPointer str) {
93110
return libc().strlen(str);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/TimeZoneSubstitutions.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import java.time.ZoneId;
3232
import java.util.TimeZone;
3333

34-
import jdk.graal.compiler.word.Word;
3534
import org.graalvm.collections.EconomicMap;
3635
import org.graalvm.nativeimage.ImageSingletons;
3736
import org.graalvm.nativeimage.Platforms;
@@ -48,12 +47,13 @@
4847
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
4948
import com.oracle.svm.core.feature.InternalFeature;
5049
import com.oracle.svm.core.handles.PrimitiveArrayView;
51-
import com.oracle.svm.core.memory.UntrackedNullableNativeMemory;
50+
import com.oracle.svm.core.headers.LibC;
5251
import com.oracle.svm.core.option.HostedOptionKey;
5352
import com.oracle.svm.core.util.VMError;
5453

5554
import jdk.graal.compiler.options.Option;
5655
import jdk.graal.compiler.options.OptionKey;
56+
import jdk.graal.compiler.word.Word;
5757

5858
/**
5959
* The following classes aim to provide full support for time zones for native-image. This
@@ -101,7 +101,7 @@ private static String getSystemTimeZoneID(String javaHome) {
101101
CCharPointer tzId = LibCHelper.SVM_FindJavaTZmd(tzMappingsPtr, contentLen);
102102
String result = CTypeConversion.toJavaString(tzId);
103103
// SVM_FindJavaTZmd returns a newly allocated string
104-
UntrackedNullableNativeMemory.free(tzId);
104+
LibC.free(tzId);
105105
return result;
106106
} finally {
107107
if (refContent != null) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/memory/NativeMemory.java

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
import static com.oracle.svm.core.Uninterruptible.CALLED_FROM_UNINTERRUPTIBLE_CODE;
2929

30-
import jdk.graal.compiler.word.Word;
3130
import org.graalvm.nativeimage.UnmanagedMemory;
3231
import org.graalvm.nativeimage.impl.UnmanagedMemorySupport;
3332
import org.graalvm.word.PointerBase;
@@ -36,24 +35,16 @@
3635
import com.oracle.svm.core.Uninterruptible;
3736
import com.oracle.svm.core.nmt.NmtCategory;
3837

38+
import jdk.graal.compiler.word.Word;
39+
3940
/**
4041
* Internal API for managing native memory. This class supports native memory tracking (NMT) and is
4142
* therefore preferred over the public API class {@link UnmanagedMemory} and its
4243
* {@link UnmanagedMemorySupport implementations}.
43-
*
44+
* <p>
4445
* All methods that allocate native memory throw an {@link OutOfMemoryError} if the memory
4546
* allocation fails. If native memory needs to be allocated from uninterruptible code, use
4647
* {@link NullableNativeMemory} instead.
47-
*
48-
* Note that NMT may cause segfaults in certain scenarios:
49-
* <ul>
50-
* <li>Native memory that was allocated outside of Java (e.g., in a C library) or via some API that
51-
* does not support NMT (e.g., {@link UnmanagedMemory}) may only be freed with
52-
* {@link UntrackedNullableNativeMemory#free}. This is necessary because NMT assumes that each
53-
* allocation has a custom header, which isn't true for such memory.</li>
54-
* <li>NMT accesses the image heap. If native memory needs to be allocated before the image heap is
55-
* mapped or after it was unmapped, {@link UntrackedNullableNativeMemory} must be used.</li>
56-
* </ul>
5748
*/
5849
public class NativeMemory {
5950
/**
@@ -139,7 +130,8 @@ public static <T extends PointerBase> T realloc(T ptr, int size, NmtCategory cat
139130
* <p>
140131
* Note that this method must <b>NOT</b> be used to free memory that was allocated via other
141132
* classes (e.g., {@link UnmanagedMemorySupport}) or outside of Native Image code (e.g., in a C
142-
* library).
133+
* library). Otherwise, segfaults can occur because NMT assumes that each allocation has a
134+
* custom header, which isn't true for such memory.
143135
*/
144136
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
145137
public static void free(PointerBase ptr) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/nmt/NmtCategory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ public enum NmtCategory {
4141
HeapDump("Heap Dump"),
4242
/** Image heap (may include GC-specific data). */
4343
ImageHeap("Image Heap"),
44+
/** Interpreter. */
45+
Interpreter("Interpreter"),
4446
/** Collected Java heap (may include GC-specific data). */
4547
JavaHeap("Java Heap"),
4648
/** Java Flight Recorder. */

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/InterpreterStubSection.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import org.graalvm.nativeimage.Platforms;
4141
import org.graalvm.nativeimage.StackValue;
4242
import org.graalvm.nativeimage.c.function.CFunctionPointer;
43-
import org.graalvm.nativeimage.impl.UnmanagedMemorySupport;
4443
import org.graalvm.word.Pointer;
4544

4645
import com.oracle.objectfile.BasicProgbitsSectionImpl;
@@ -59,6 +58,8 @@
5958
import com.oracle.svm.core.graal.code.SubstrateCallingConventionType;
6059
import com.oracle.svm.core.hub.DynamicHub;
6160
import com.oracle.svm.core.jdk.InternalVMMethod;
61+
import com.oracle.svm.core.memory.NativeMemory;
62+
import com.oracle.svm.core.nmt.NmtCategory;
6263
import com.oracle.svm.core.util.VMError;
6364
import com.oracle.svm.hosted.image.AbstractImage;
6465
import com.oracle.svm.hosted.image.NativeImage;
@@ -356,7 +357,7 @@ public static Object leaveInterpreter(CFunctionPointer compiledEntryPoint, Inter
356357

357358
Pointer stackBuffer = Word.nullPointer();
358359
if (stackSize > 0) {
359-
stackBuffer = ImageSingletons.lookup(UnmanagedMemorySupport.class).malloc(Word.unsigned(stackSize));
360+
stackBuffer = NativeMemory.malloc(Word.unsigned(stackSize), NmtCategory.Interpreter);
360361
accessHelper.setSp(leaveData, stackSize, stackBuffer);
361362
}
362363

@@ -421,7 +422,7 @@ public static Object leaveInterpreter(CFunctionPointer compiledEntryPoint, Inter
421422
} finally {
422423
if (stackSize > 0) {
423424
VMError.guarantee(stackBuffer.isNonNull());
424-
ImageSingletons.lookup(UnmanagedMemorySupport.class).free(stackBuffer);
425+
NativeMemory.free(stackBuffer);
425426
}
426427
}
427428

0 commit comments

Comments
 (0)