Skip to content

Throw NoSuchFieldException when call getInt() method #565

@GGGGGHT

Description

@GGGGGHT

Enviroment Infomation

OS

macOS Monterey
Version 12.3.1

java -version

java version "17.0.3" 2022-04-19 LTS
Java(TM) SE Runtime Environment (build 17.0.3+8-LTS-111)
Java HotSpot(TM) 64-Bit Server VM (build 17.0.3+8-LTS-111, mixed mode, sharing)

btrace version

BTrace v.2.2.2 (c8f81cc)

target

public abstract class HelloWorld extends HelloWorldBase {
    protected int field = 0;

    public static void main(String[] args) throws Exception {
        System.out.println(ProcessHandle.current().pid());
        System.out.println("ready when you are ...");
        System.in.read();

        callA();
    }

    private static void callA() {
        System.out.println("HelloWorld#callA");
        HelloWorld instance = new HelloWorldExt();
        long x = System.nanoTime();
        instance.callA("hello", 13);
        System.out.println("dur = " + (System.nanoTime() - x));
    }
    

    private void callA(String a, int b) {
        field++;
        callB(callC(a, b));
        field--;
    }

    private void callB(String s) {
        field++;
        System.out.println("You want " + s);
        field--;
    }

    protected abstract String callC(String a, int b);
}

final class HelloWorldExt extends HelloWorld {
    @Override
    protected String callC(String a, int b) {
        try {
            field++;
            String s = a + "-" + b;
            for (int i = 0; i < 100; i++) {
                s = callD(s);
            }
            return s;
        } finally {
            field--;
        }
    }
}

abstract class HelloWorldBase {
    protected final String callD(String s) {
        return "# " + s;
    }
}

script content

import org.openjdk.btrace.core.annotations.BTrace;
import org.openjdk.btrace.core.annotations.Kind;
import org.openjdk.btrace.core.annotations.Location;
import org.openjdk.btrace.core.annotations.OnMethod;
import org.openjdk.btrace.core.annotations.ProbeMethodName;
import org.openjdk.btrace.core.annotations.Self;

import static org.openjdk.btrace.core.BTraceUtils.Reflective.getInt;
import static org.openjdk.btrace.core.BTraceUtils.println;
import static org.openjdk.btrace.core.BTraceUtils.str;

@BTrace
public class HelloWorldTrace {
    @OnMethod(clazz="HelloWorld", method="/call.*/", type="void (java.lang.String, int)",location=@Location(Kind.ENTRY))
    public static void onMethod(@ProbeMethodName(fqn = true) String pmn, @Self Object thiz) {
        println("Hello from method " + pmn);
        println("field = " + str(getInt("field", thiz)));
    }
}

command

btrace ${pid} HelloWorldTrace.java

what happen

Java HotSpot(TM) 64-Bit Server VM warning: Option AllowRedefinitionToAddDeleteMethods was deprecated in version 13.0 and will likely be removed in a future release.
btrace INFO: Attaching BTrace to PID: 69347
btrace INFO: Successfully started BTrace probe: HelloWorldTrace.java
Hello from method private void HelloWorld#callA(java.lang.String, int)

! ERROR
java.lang.RuntimeException: java.lang.NoSuchFieldException: field
	at org.openjdk.btrace.core.BTraceUtils.translate(BTraceUtils.java:3124)
	at org.openjdk.btrace.core.BTraceUtils.lambda$getField$0(BTraceUtils.java:3044)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at org.openjdk.btrace.core.BTraceUtils.getField(BTraceUtils.java:3035)
	at org.openjdk.btrace.core.BTraceUtils.access$400(BTraceUtils.java:65)
	at org.openjdk.btrace.core.BTraceUtils$Reflective.getInt(BTraceUtils.java:5395)
	at HelloWorld.callA(HelloWorld.java)
	at HelloWorld.callA(HelloWorld.java:16)
	at HelloWorld.main(Unknown Source)
Caused by: java.lang.NoSuchFieldException: field
	at java.base/java.lang.Class.getDeclaredField(Class.java:2610)
	at org.openjdk.btrace.core.BTraceUtils.lambda$getField$0(BTraceUtils.java:3039)
	... 7 more

modify script

import org.openjdk.btrace.core.annotations.BTrace;
import org.openjdk.btrace.core.annotations.Kind;
import org.openjdk.btrace.core.annotations.Location;
import org.openjdk.btrace.core.annotations.OnMethod;
import org.openjdk.btrace.core.annotations.ProbeMethodName;
import org.openjdk.btrace.core.annotations.Self;
import java.lang.Class;
import java.lang.reflect.Field;
import static org.openjdk.btrace.core.BTraceUtils.*;

@BTrace
public class HelloWorldTrace {
    @OnMethod(clazz = "HelloWorld", method = "callA", type = "void (java.lang.String,int)", location = @Location(Kind.RETURN))
    public static void onMethod(@ProbeMethodName(fqn = true) String pmn, @Self Object thiz) {
        println("clazz = " + name(classOf(thiz)));
        println("Hello from method " + pmn);
    }
}

Reprint when I modify the script, the clazz print HelloWorldExt. The complete information is as follows

btrace INFO: Attaching BTrace to PID: 21811
btrace INFO: Successfully started BTrace probe: HelloWorldTrace.java
clazz = HelloWorldExt

Hello from method private void HelloWorld#callA(java.lang.String, int)

confused

  • I marked clazz on the annotation of onmethod is HelloWorld but clazz print HelloWorldExt
  • Why is NoSuchFieldException thrown

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions