/*******************************************************************************
* Copyright (c) 2010 Freescale Semiconductor.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Serge Beauchamp (Freescale Semiconductor) - initial API and implementation
*******************************************************************************/
package com.freescale.deadlockpreventer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.ArrayList;
public class PreMain {
public static void premain(String agentArguments, Instrumentation instrumentation) {
Analyzer.instance().activate();
Transformer transformer = new Transformer();
instrumentation.addTransformer(transformer, true);
InputStream stream = PreMain.class.getResourceAsStream("config.ini");
if (stream != null) {
ArrayList<String> classesToInstrument = new ArrayList<String>();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
try {
String line = reader.readLine();
while (line != null) {
line = line.trim();
if (!line.startsWith("##")) {
String arguments[] = line.split(" ");
if (arguments.length < 4) {
System.out.println("invalid arguments in config.ini: " + line);
System.out.println("usage: mode classname methodname signature [unscoped]");
System.out.println(" where 'mode' is one of: L U L(n) U(n)");
System.out.println(" 'unscoped' indicates that the object is not used for locking a scope, but for signaling");
}
else {
String mode = arguments[0];
String className = arguments[1];
String methodName = arguments[2];
String signature = arguments[3];
int modeInt = parseMode(mode);
boolean unscoped = arguments.length > 4 && arguments[4].equals("unscoped");
transformer.register(modeInt, className, methodName, signature, unscoped);
if (!classesToInstrument.contains(className))
classesToInstrument.add(className);
}
}
line = reader.readLine();
}
} catch (IOException e) {
} finally {
try {
stream.close();
} catch (IOException e) {
}
}
for (String classToInstrument: classesToInstrument) {
try {
Class<?> cls = Class.forName(classToInstrument.replace('/','.'));
instrumentation.retransformClasses(cls);
} catch (RuntimeException e) {
// ignore since frozen classes return this error
} catch (ClassNotFoundException e) {
// ignore
} catch (UnmodifiableClassException e) {
e.printStackTrace();
}
}
}
Analyzer.instance().enable();
}
private static int parseMode(String mode) {
if (mode.equals("L"))
return Analyzer.LOCK_NORMAL;
if (mode.equals("U"))
return Analyzer.UNLOCK_NORMAL;
if (mode.equals("L(n)"))
return Analyzer.LOCK_COUNTED;
if (mode.equals("U(n)"))
return Analyzer.UNLOCK_COUNTED;
return 0;
}
}