murkaje / npe-blame-agent

JVMTI Agent to display detailed cause message in otherwise empty NullPointerException
9 stars 0 forks source link

Bad allocation inside switch statement #10

Open m4tiz5zktonj opened 4 years ago

m4tiz5zktonj commented 4 years ago

Hello.

Thanks for the great tool!

I have issues with enabled npeblame on Windows 10 1909.

My environment:

D:\>java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)

D:\>javac -version
javac 1.8.0_202

npeblame.dll is the one from GitHub's releases (npe-blame-1.1-win64.zip).

Example class:

public class Test {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        test(null, 1);
        System.out.println(System.currentTimeMillis() - start);
    }
    private static boolean test(Object value, int i) {
        switch(i) {
            case 0: return true;
            default: {
                try {
                    return value.getClass() != null; // NPE
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }
        }
    }
}

With npeblame code execution time and RAM consumption are very big and NPE message is empty:

>javac Test.java

>java Test
java.lang.NullPointerException
        at Test.test(Test.java:12)
        at Test.main(Test.java:4)
3

>java -agentpath:D:\some\path\npeblame.dll Test
2020-05-20 21:15:21.034 I [JVMTI] OnLoad npe-blame-agent
2020-05-20 21:16:39.379 E [ExceptionCallback] Failed to run exception callback: bad allocation
java.lang.NullPointerException
        at Test.test(Test.java:12)
        at Test.main(Test.java:4)
78297

Are there any ways to fix this?

murkaje commented 4 years ago

Thanks for the error report, i confirmed the error was fixed in commit 8be561f2e181ac15a4eff54bb7851f7a06f1e53a but no releases have been done in a while. I'll try to make a release soon.

Hadn't been prioritizing this project since the original SAP JVM nullpointer messages had been planned to be included in openjdk, which was released in JDK 14, although under the default disabled flag -XX:+ShowCodeDetailsInExceptionMessages

murkaje commented 4 years ago

Done: https://github.com/murkaje/npe-blame-agent/releases/tag/v1.2

m4tiz5zktonj commented 4 years ago

Thanks, but unfortunately I get the following error with 1.2:

Error occurred during initialization of VM
Could not find agent library D:\some\path\npeblame.dll in absolute path, with error: Can't find dependent libraries

It seems, that this is due to the missing ucrtbased.dll. Google says, that this is Visual Studio's debug build dll. Could you, please, add this dll to GitHub's releases too or replace npeblame.dll with release binary?

murkaje commented 4 years ago

Replaced the windows binary with a release build version.

Apparently cmake works quite differently on windows and the default build type wasn't picked up and the tests didn't trip on this as they had msvc installed with ucrtbased.dll

m4tiz5zktonj commented 4 years ago

This test class works fine now, though -agentpath:D:\some\path\npeblame.dll=debug and -agentpath:D:\some\path\npeblame.dll=trace give exactly the same output as with default logging level. It's not a big deal for me, as all npeblame logging is completely swallowed by Tanuki's Java Service Wrapper I have to use.

It seems, that I'd stay with 1.1. On my real project at work npeblame 1.2 changes application behavior in a very strange way. For example, this method sometimes returns null:

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.LogRecord;

private static String getThrowable(LogRecord record) {
    String throwable = "";
    if (record.getThrown() != null) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        pw.println();
        record.getThrown().printStackTrace(pw);
        pw.close();
        throwable = sw.toString();
    }
    return throwable;
}

If I set a conditional breakpoint on the next line to the line, where this method is called, IntelliJ IDEA stops there and shows, that variable, to which this method return value was assigned, is null. But second evaluation of getThrowable() method in debugger with the same arguments returns expected not null result. Also debugger does not stops on breakpoints with conditions sw.toString() == null on throwable = sw.toString(); line and with throwable == null on return throwable;. I can't neither create test class to reproduce this, nor share the code of my project, so, probably, this is a dead end.

Problem with switch statements is solved, so this issue can be closed.

Thank you very much for your wonderful project! It really helps in everyday work as NPEs are not so rare, and unlikely we'll move to Java 14 in a foreseeable future, so npeblame is the only way to deal with them.