Skip to content

Instantly share code, notes, and snippets.

@ytoshima
Created February 2, 2012 17:41
Show Gist options
  • Save ytoshima/1724808 to your computer and use it in GitHub Desktop.
Save ytoshima/1724808 to your computer and use it in GitHub Desktop.
Simple JNI examples for certain crashes
Steps to build on windows:
1. Compile java source
javac JniEx.java
2. Make header file
javah -jni JniEx
3. build dll
build.bat
# This needs to be run in visual studio express command prompt
# since the batch file uses cl.exe and link.exe.
For linux, ran make (using Makefile) to build libJniEx.so. The JNI include path is hardcoded in Makefile (see JNI_HDR_BASE line). Change the line for your environment.
Linux output example:
1.5:
$ D_LIBRARY_PATH=$(pwd) ~/local/jdk1.5.0_17/bin/java JniEx alloc
:
23821 0x94fcfe8
23822 0x0
Exception in thread "CompilerThread0" java.lang.OutOfMemoryError: requested 108776 bytes for Chunk::new. Out of swap space?
1.6:
$ LD_LIBRARY_PATH=$(pwd) ~/local/jdk1.6.0_26/bin/java JniEx alloc
:
24370 0xffffffffbffc4008
24371 0xffffffffbffde008
24372 0x0
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (malloc) failed to allocate 119248 bytes for Chunk::new
# An error report file with more information is saved as:
# /home/yoshi/lang/j/vm_exit_out_of_memory/hs_err_pid29135.log
Aborted (core dumped)
rem change java_home as needed
set java_home=c:\Program Files (x86)\Java\jdk1.6.0_22
set java_include="%java_home%"\include
cl /c /I. /I%java_include% /I%java_include%\win32 JniEx.cpp
rem use /OUT:<filename> to change output filename
link /dll JniEx.obj
#include "JniEx.h"
#include <stdlib.h>
void bad_func()
{
int *ip = (int*)0xbffffffe;
*ip = 1;
}
JNIEXPORT void JNICALL Java_JniEx_crash (JNIEnv *env, jclass cls) {
bad_func();
}
JNIEXPORT jlong JNICALL Java_JniEx_malloc
(JNIEnv *env, jclass cls, jint sz) {
return (jlong)malloc(sz);
}
import java.util.regex.*;
import javax.xml.parsers.*;
import org.xml.sax.InputSource;
import org.w3c.dom.*;
import java.io.*;
public class JniEx {
static {
System.loadLibrary("JniEx");
}
public static void usage() {
String msg = "usage: java JniEx <crash|alloc>";
System.out.println(msg);
}
public static void main(String[] args) {
String op = "crash";
if (args.length > 0) {
if (args[0].equals("alloc")) {
op = "alloc";
}
}
if (op.equals("crash")) {
System.out.println("calling crash...");
crash();
} else if (op.equals("alloc")) {
System.out.println("allocating mem");
int i = 0;
while (true) {
//long addr = malloc(1024*1024);
long addr = malloc(1024*102);
System.out.println(String.format("%6d %#x", i, addr));
if (addr == 0) break;
i++;
}
doSomething();
} else {
usage();
}
}
public static native void crash();
public static native long malloc(int size);
static void doSomething() {
doRegEx();
doXML();
}
static void doRegEx() {
String[] patterns = {"^java", "^javax", "^javax.swing", "javax\\.*"};
String[] strings = {"java.lang.String", "javax.swing.JFrame",
"javax.xml.Node", "java.util.Vector"};
for (int i = 0; i < 11000; i++) {
for (String ps : patterns) {
Pattern p = Pattern.compile(ps);
for (String tx : strings) {
Matcher m = p.matcher(tx);
if (m.matches()) {
incMCount();
}
}
}
}
}
public static long mcount = 0;
public static void incMCount() { mcount++; }
public static long getMCount() { return mcount; }
static void doXML() {
try {
for (int i = 0; i < 11000; i++) {
doXML0();
}
} catch (Exception e) { e.printStackTrace(); }
}
static void doXML0() throws Exception {
DocumentBuilderFactory fac = DocumentBuilderFactory.newInstance();
DocumentBuilder db = fac.newDocumentBuilder();
StringReader sr = new StringReader("<books> <book><author>joe</author><title>foo</title></book> <book><author>joe2</author><title>foo2</title></book> <book><author>joe3</author><title>foo3</title></book> <book><author>joe4</author><title>foo4</title></book> <book><author>joe5</author><title>foo5</title></book> </books>");
Document doc = db.parse(new InputSource(sr));
walkNode(doc);
}
static void walkNode(Node n) {
NodeList nl = n.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node cn = nl.item(i);
nvisited++;
walkNode(cn);
}
}
static long nvisited = 0L;
}
SRC = JniEx.cpp
OLIB = libJniEx.so
all: $(OLIB)
JNI_HDR_BASE = /home/yoshi/local/jdk1.5.0_06/include
CXXFLAGS = -o $(OLIB) -shared -Wl,-soname,$(OLIB) -I$(JNI_HDR_BASE) -I$(JNI_HDR_BASE)/linux $(SRC) -static -lc
$(OLIB): $(SRC)
$(CXX) $(CXXFLAGS)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment