Skip to content

Commit

Permalink
broker leak detector
Browse files Browse the repository at this point in the history
  • Loading branch information
shabanovd committed Apr 5, 2016
1 parent 3578f11 commit 3e054b0
Show file tree
Hide file tree
Showing 8 changed files with 685 additions and 0 deletions.
74 changes: 74 additions & 0 deletions broker-leak-detector/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.existdb</groupId>
<artifactId>broker-leak-detector</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
<dependency>
<groupId>org.kohsuke</groupId>
<artifactId>asm5</artifactId>
<version>5.0.1</version>
</dependency>

<dependency>
<groupId>args4j</groupId>
<artifactId>args4j</artifactId>
<version>2.0.16</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Agent-Class>org.exist.agent.AgentMain</Agent-Class>
<Premain-Class>org.exist.agent.AgentMain</Premain-Class>
<Main-Class>org.exist.agent.Main</Main-Class>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
</manifestEntries>
</transformer>
</transformers>
<relocations>
<relocation>
<pattern>org.kohsuke.args4j</pattern>
<shadedPattern>org.exist.agent.args4j</shadedPattern>
</relocation>
<relocation>
<pattern>org.kohsuke.asm3</pattern>
<shadedPattern>org.exist.agent.asm3</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>
149 changes: 149 additions & 0 deletions broker-leak-detector/src/main/java/org/exist/agent/AgentMain.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package org.exist.agent;

import org.exist.agent.transform.ClassTransformSpec;
import org.exist.agent.transform.CodeGenerator;
import org.exist.agent.transform.MethodAppender;
import org.exist.agent.transform.TransformerImpl;

import java.io.*;
import java.lang.instrument.Instrumentation;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

/**
* @author <a href="mailto:[email protected]">Dmitriy Shabanov</a>
*/
public class AgentMain {


public static void premain(String arguments, Instrumentation instrumentation) throws Exception {

int port = 12251;

if (arguments != null) {
for (String argument : arguments.split(",")) {
if (argument.startsWith("http=")) {
port = Integer.parseInt(argument.substring(argument.indexOf('=') + 1));
}
}
}

System.err.println("eXist-db agent installed");

instrumentation.addTransformer(new TransformerImpl(createSpec()),true);

//instrumentation.retransformClasses(...class);

runHttpServer(port);
}

private static void runHttpServer(int port) throws IOException {
final ServerSocket ss = new ServerSocket();
ss.bind(new InetSocketAddress("localhost", port));
System.err.println("Serving broker leak info on http://localhost:"+port+"/");
final ExecutorService es = Executors.newCachedThreadPool(new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
}
});
es.submit(new Callable<Void>() {
public Void call() throws Exception {
while (true) {
final Socket s = ss.accept();
es.submit(new Callable<Void>() {
public Void call() throws Exception {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
// Read the request line (and ignore it)
in.readLine();

PrintWriter w = new PrintWriter(new OutputStreamWriter(s.getOutputStream(), "UTF-8"));
w.print("HTTP/1.0 200 OK\r\nContent-Type: text/plain;charset=UTF-8\r\n\r\n");
Listener.dump(w);
} finally {
s.close();
}
return null;
}
});
}
}
});
}


static List<ClassTransformSpec> createSpec() {
return Arrays.asList(
new ClassTransformSpec("org/exist/storage/DBBroker",
new OccupationInterceptor(),
new ReleaseInterceptor(),
new Skip("<init>", "*"),
new Skip("<clinit>", "*"),
new Skip("initIndexModules", "*"),
new Skip("addContentLoadingObserver", "*"),
new Skip("clearContentLoadingObservers", "*"),
new Skip("setId", "*"),
new CheckerInterceptor()
)
);
}


private static class OccupationInterceptor extends MethodAppender {
OccupationInterceptor() {
super("incReferenceCount", "()V", false);
}

@Override
protected void append(CodeGenerator g) {
g.invokeAppStatic(Listener.class,"occupation",
new Class[]{Object.class},
new int[]{0});
}
}

private static class ReleaseInterceptor extends MethodAppender {
ReleaseInterceptor() {
super("decReferenceCount", "()V", false);
}

@Override
protected void append(CodeGenerator g) {
g.invokeAppStatic(Listener.class,"release",
new Class[]{Object.class},
new int[]{0});
}
}

private static class CheckerInterceptor extends MethodAppender {
CheckerInterceptor() {
super("*", "", false);
}

@Override
protected void append(CodeGenerator g) {
g.invokeAppStatic(Listener.class,"check",
new Class[]{Object.class},
new int[]{0});
}
}

private static class Skip extends MethodAppender {
Skip(String name, String signature) {
super(name, signature, true);
}

@Override
protected void append(CodeGenerator g) {
}
}
}
Loading

0 comments on commit 3e054b0

Please sign in to comment.