Skip to content

[GR-53359] Provide native debugging friendly classloadername based on ClassLoader.nameAndId #8885

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

Merged
merged 4 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This changelog summarizes major changes to GraalVM Native Image.
* (GR-52578) Print information about embedded resources into `embedded-resources.json` using the `-H:+GenerateEmbeddedResourcesFile` option.
* (GR-51172) Add support to catch OutOfMemoryError exceptions on native image if there is no memory left.
* (GR-43837) `--report-unsupported-elements-at-runtime` is now enabled by default and the option is deprecated.
* (GR-53359) Provide the `.debug_gdb_scripts` section that triggers auto-loading of `svmhelpers.py` in GDB. Remove single and double quotes from `ClassLoader.nameAndId` in the debuginfo.

## GraalVM for JDK 22 (Internal Version 24.0.0)
* (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -90,9 +90,11 @@ public String uniqueShortLoaderName(ClassLoader loader) {
String name = SubstrateUtil.classLoaderNameAndId(loader);
// name will look like "org.foo.bar.FooBarClassLoader @1234"
// trim it down to something more manageable
// escaping quotes in the classlaoder name does not work in GDB
// but the name is still unique without quotes
name = SubstrateUtil.stripPackage(name);
name = stripOuterClass(name);
name = name.replace(" @", "_");
name = name.replace(" @", "_").replace("'", "").replace("\"", "");
return name;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand All @@ -24,9 +24,19 @@
*/
package com.oracle.svm.hosted.image;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;

import com.oracle.svm.core.c.CGlobalData;
import com.oracle.svm.core.c.CGlobalDataFactory;
import com.oracle.svm.core.config.ConfigurationValues;
import com.oracle.svm.core.heap.Heap;
import com.oracle.svm.hosted.c.CGlobalDataFeature;
import com.oracle.svm.util.ReflectionUtil;
import jdk.graal.compiler.core.common.CompressEncoding;
import jdk.graal.compiler.debug.DebugContext;
import jdk.graal.compiler.printer.GraalDebugHandlersFactory;
import com.oracle.svm.core.graal.meta.RuntimeConfiguration;
Expand All @@ -49,6 +59,8 @@
import com.oracle.svm.hosted.ProgressReporter;
import com.oracle.svm.hosted.image.sources.SourceManager;
import com.oracle.svm.hosted.util.DiagnosticUtils;
import org.graalvm.word.PointerBase;
import org.graalvm.word.WordFactory;

@AutomaticallyRegisteredFeature
@SuppressWarnings("unused")
Expand Down Expand Up @@ -97,6 +109,21 @@ public void beforeAnalysis(BeforeAnalysisAccess access) {
var accessImpl = (FeatureImpl.BeforeAnalysisAccessImpl) access;
bfdNameProvider.setNativeLibs(accessImpl.getNativeLibraries());
}

/*
* Ensure ClassLoader.nameAndId is available at runtime for type lookup from gdb
*/
access.registerAsAccessed(ReflectionUtil.lookupField(ClassLoader.class, "nameAndId"));

CompressEncoding compressEncoding = ImageSingletons.lookup(CompressEncoding.class);
CGlobalData<PointerBase> compressedShift = CGlobalDataFactory.createWord(WordFactory.signed(compressEncoding.getShift()), "__svm_compressed_shift");
CGlobalData<PointerBase> useHeapBase = CGlobalDataFactory.createWord(WordFactory.unsigned(compressEncoding.hasBase() ? 1 : 0), "__svm_use_heap_base");
CGlobalData<PointerBase> oopTagsMask = CGlobalDataFactory.createWord(WordFactory.unsigned(Heap.getHeap().getObjectHeader().getReservedBitsMask()), "__svm_oop_tags_mask");
CGlobalData<PointerBase> objectAlignment = CGlobalDataFactory.createWord(WordFactory.unsigned(ConfigurationValues.getObjectLayout().getAlignment()), "__svm_object_alignment");
CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(compressedShift);
CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(useHeapBase);
CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(oopTagsMask);
CGlobalDataFeature.singleton().registerWithGlobalHiddenSymbol(objectAlignment);
}

@Override
Expand Down Expand Up @@ -134,11 +161,29 @@ public boolean isLoadable() {
};
};

Supplier<BasicProgbitsSectionImpl> makeGDBSectionImpl = () -> {
var content = AssemblyBuffer.createOutputAssembler(objectFile.getByteOrder());
// 1 -> python file
content.writeByte((byte) 1);
content.writeString("./svmhelpers.py");
return new BasicProgbitsSectionImpl(content.getBlob()) {
@Override
public boolean isLoadable() {
return false;
}
};
};

var imageClassLoader = accessImpl.getImageClassLoader();
objectFile.newUserDefinedSection(".debug.svm.imagebuild.classpath", makeSectionImpl.apply(DiagnosticUtils.getClassPath(imageClassLoader)));
objectFile.newUserDefinedSection(".debug.svm.imagebuild.modulepath", makeSectionImpl.apply(DiagnosticUtils.getModulePath(imageClassLoader)));
objectFile.newUserDefinedSection(".debug.svm.imagebuild.arguments", makeSectionImpl.apply(DiagnosticUtils.getBuilderArguments(imageClassLoader)));
objectFile.newUserDefinedSection(".debug.svm.imagebuild.java.properties", makeSectionImpl.apply(DiagnosticUtils.getBuilderProperties()));

Path svmDebugHelper = Path.of(System.getProperty("java.home"), "lib/svm/debug/svmhelpers.py");
if (Files.exists(svmDebugHelper)) {
objectFile.newUserDefinedSection(".debug_gdb_scripts", makeGDBSectionImpl.get());
}
}
}
ProgressReporter.singleton().setDebugInfoTimer(timer);
Expand Down