Skip to content

UnsolvedSymbolException When Slicing Code Using Reflected sun.misc.Unsafe (JDK Internal Class) #58

@bystc

Description

@bystc

Description
The slicing tool crashes with an UnsolvedSymbolException when attempting to slice Java code that uses reflection to access sun.misc.Unsafe—a non-public internal class of the JDK. The exception occurs during the symbol resolution phase, as the tool fails to recognize or locate the Unsafe class, halting the slicing process entirely.

Steps to Reproduce
Create a Java file named UnsafeSliceCrash.java with the following code (includes reflection to access Unsafe and a clear slicing criterion):

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class UnsafeSliceCrash {
    // Slicing Criterion: Track the value of arr[0] (expected output: 42)
    public static void main(String[] args) throws Exception {
        // Step 1: Get Unsafe instance via reflection (since Unsafe has no public constructor)
        Unsafe unsafe = getUnsafe();

        // Step 2: Initialize an int array (initial value of arr[0] is 0)
        int[] arr = new int[1];

        // Step 3: Modify array memory directly using Unsafe's native method
        unsafe.putInt(arr, 100, 42); // Overwrites arr[0] with 42

        // **Slicing Criterion: Print modified arr[0]**
        System.out.println(arr[0]);
    }

    // Helper method to get Unsafe via reflection
    private static Unsafe getUnsafe() throws Exception {
        Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
        unsafeField.setAccessible(true); // Bypass access restrictions
        return (Unsafe) unsafeField.get(null);
    }
}

Expected Behavior
The tool should either:
Successfully resolve the sun.misc.Unsafe class (even as a JDK internal class) and complete the slicing process, or
Throw a clear, handled error (e.g., "Unsupported JDK internal class") instead of a fatal UnsolvedSymbolException that aborts slicing.

Actual Behavior
The tool crashes immediately during symbol resolution, throwing UnsolvedSymbolException for the Unsafe class. No slicing is performed, and the following stack trace is generated:

Exception in thread "main" UnsolvedSymbolException{context='null', name='Unsafe', cause='null'}
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(JavaParserFacade.java:643)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(JavaParserFacade.java:618)
        at com.github.javaparser.symbolsolver.JavaSymbolSolver.toResolvedType(JavaSymbolSolver.java:281)
        at com.github.javaparser.ast.type.ClassOrInterfaceType.resolve(ClassOrInterfaceType.java:315)
        at com.github.javaparser.ast.type.ClassOrInterfaceType.resolve(ClassOrInterfaceType.java:64)
        at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:430)
        at es.upv.mist.slicing.nodes.VariableVisitor.visit(VariableVisitor.java:38)
        at com.github.javaparser.ast.expr.VariableDeclarationExpr.accept(VariableDeclarationExpr.java:118)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:259)
        at es.upv.mist.slicing.graphs.GraphNodeContentVisitor.visit(GraphNodeContentVisitor.java:91)
        at com.github.javaparser.ast.stmt.ExpressionStmt.accept(ExpressionStmt.java:77)
        at es.upv.mist.slicing.graphs.GraphNodeContentVisitor.startVisit(GraphNodeContentVisitor.java:21)
        at es.upv.mist.slicing.nodes.VariableVisitor.startVisit(VariableVisitor.java:113)
        at es.upv.mist.slicing.nodes.GraphNode.extractVariables(GraphNode.java:66)
        at es.upv.mist.slicing.nodes.GraphNode.<init>(GraphNode.java:49)
        at es.upv.mist.slicing.nodes.GraphNode.<init>(GraphNode.java:43)
        at es.upv.mist.slicing.graphs.jsysdg.JSysCFG$Builder.connectTo(JSysCFG.java:185)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.connectTo(CFGBuilder.java:72)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:132)
        at es.upv.mist.slicing.graphs.exceptionsensitive.ESCFG$Builder.visit(ESCFG.java:398)
        at es.upv.mist.slicing.graphs.exceptionsensitive.ESCFG$Builder.visit(ESCFG.java:91)
        at com.github.javaparser.ast.stmt.ExpressionStmt.accept(ExpressionStmt.java:77)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$19(VoidVisitorAdapter.java:109)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:109)
        at com.github.javaparser.ast.stmt.BlockStmt.accept(BlockStmt.java:76)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visitCallableDeclarationBody(CFGBuilder.java:383)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visitCallableDeclaration(CFGBuilder.java:371)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:355)
        at es.upv.mist.slicing.graphs.cfg.CFGBuilder.visit(CFGBuilder.java:37)
        at com.github.javaparser.ast.body.MethodDeclaration.accept(MethodDeclaration.java:104)
        at es.upv.mist.slicing.graphs.jsysdg.JSysCFG.build(JSysCFG.java:50)
        at es.upv.mist.slicing.graphs.jsysdg.JSysDG$Builder.buildCFG(JSysDG.java:74)
        at es.upv.mist.slicing.graphs.sdg.SDG$Builder$1.visit(SDG.java:144)
        at es.upv.mist.slicing.graphs.sdg.SDG$Builder$1.visit(SDG.java:136)
        at com.github.javaparser.ast.body.MethodDeclaration.accept(MethodDeclaration.java:104)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$31(VoidVisitorAdapter.java:154)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:154)
        at com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.accept(ClassOrInterfaceDeclaration.java:98)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.lambda$visit$43(VoidVisitorAdapter.java:175)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at com.github.javaparser.ast.NodeList.forEach(NodeList.java:290)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:175)
        at com.github.javaparser.ast.CompilationUnit.accept(CompilationUnit.java:133)
        at com.github.javaparser.ast.visitor.VoidVisitorAdapter.visit(VoidVisitorAdapter.java:630)
        at com.github.javaparser.ast.NodeList.accept(NodeList.java:282)
        at es.upv.mist.slicing.graphs.sdg.SDG$Builder.buildCFGs(SDG.java:136)
        at es.upv.mist.slicing.graphs.sdg.SDG$Builder.build(SDG.java:126)
        at es.upv.mist.slicing.graphs.jsysdg.JSysDG$Builder.build(JSysDG.java:44)
        at es.upv.mist.slicing.graphs.sdg.SDG.build(SDG.java:73)
        at es.upv.mist.slicing.cli.Slicer.slice(Slicer.java:208)
        at es.upv.mist.slicing.cli.Slicer.main(Slicer.java:286)

Root Cause Hypothesis
sun.misc.Unsafe is a non-public internal class of the JDK, not part of the standard Java API. The tool’s underlying symbol resolver (powered by JavaParser) is not configured to recognize or resolve JDK internal classes. When the parser encounters references to Unsafe, it cannot find its symbol definition, leading to the fatal UnsolvedSymbolException.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions