LocalProcess.PROCESS_IS_ALIVE
if process is not terminated
* after timeout.
*/
public int waitFor(long timeMillisec) throws InterruptedException {
int exitCode = super.waitFor(timeMillisec);
if (exitCode != LocalProcess.PROCESS_IS_ALIVE) {
waitForAllReaders(timeMillisec);
}
return exitCode;
}
/**
* Writes jdbCommand to jdb's input stream.
*/
public synchronized void sendCommand(String jdbCommand) {
if (terminated()) {
throw new Failure("Attempt to send command :" + jdbCommand + "\t to terminated jdb.");
}
if (jdbCommand != null) {
String logCmd;
if (!jdbCommand.endsWith(lineSeparator)) {
logCmd = jdbCommand;
jdbCommand += lineSeparator;
} else {
// we don't want to log the line separator
logCmd = jdbCommand.substring(0, jdbCommand.length() - lineSeparator.length());
}
launcher.getLog().display("Sending command: " + logCmd);
jdbStdinWriter.print(jdbCommand);
jdbStdinWriter.flush();
synchronized(flog) {
flog.print(/*LOG_COMMAND_PREFIX +*/ jdbCommand);
flog.flush();
}
fin.print(jdbCommand);
fin.flush();
if (jdbStdinWriter.checkError()) {
throw new Failure("Unexpected IO error while writing command <" + jdbCommand + "> to jdb stdin stream");
}
}
}
/**
* Sends command to jdb's input stream, waits for compound promt received,
* and then returns reply from jdb's output stream.
*
* @param command string representing full command with all arguments if any.
*/
public String[] receiveReplyFor(String command) {
return receiveReplyFor(command, true);
}
/**
* Sends command to jdb's input stream, waits for promt received,
* and then returns reply from jdb's output stream.
*
* @param command string representing full command with all arguments if any.
* @param compoundPromptOnly read output until compound prompt is found.
*/
public String[] receiveReplyFor(String command, boolean compoundPromptOnly) {
return receiveReplyFor(command, compoundPromptOnly, 1);
}
/**
* Sends command to jdb's input stream, waits for given number of promts received,
* and then returns reply from jdb's output stream.
*
* @param command string representing full command with all arguments if any.
* @param compoundPromptOnly read output until compound prompt is found.
* @param count number of prompt instances to found.
*/
public String[] receiveReplyFor(String command, boolean compoundPromptOnly, int count) {
if (command == null) {
return null;
}
int startPos = stdoutBuffer.length();
sendCommand(command);
return receiveReply(startPos, compoundPromptOnly, count);
}
/**
* Sends command to jdb's input stream, waits for specified message to be received,
* and then returns reply from jdb's output stream.
*
* @param command string representing full command with all arguments if any.
* @param waitMsg string representing the message that must be sent back before returing.
*/
public String[] receiveReplyForWithMessageWait(String command, String waitMsg) {
if (command == null) {
return null;
}
int startPos = stdoutBuffer.length();
sendCommand(command);
waitForMessage(startPos, waitMsg);
return receiveReply(startPos, true, 1);
}
/**
* Waits for compound prompt and returns reply from jdb stdout
* beginning from startPos in the stdoutBuffer.
*
* @param startPos start position for search in stdoutBuffer.
*/
public String[] receiveReply(int startPos) {
return receiveReply(startPos, true);
}
/**
* Waits for particular prompt and returns reply from jdb stdout
* beginning from startPos in the stdoutBuffer.
*
* @param startPos start position for search in stdoutBuffer.
* @param compoundPromptOnly waits for compound prompt only.
*/
public String[] receiveReply(int startPos, boolean compoundPromptOnly) {
return receiveReply(startPos, compoundPromptOnly, 1);
}
/**
* Waits for count number of prompts and returns reply from jdb stdout
* beginning from startPos in the stdoutBuffer.
*
* @param startPos start position for search in stdoutBuffer.
* @param compoundPromptOnly waits for compound prompt only.
* @param count number of prompt instances to wait for.
*/
public String[] receiveReply(int startPos, boolean compoundPromptOnly, int count) {
nsk.share.Failure e = null;
try {
waitForPrompt(startPos, compoundPromptOnly, count);
} catch (nsk.share.Failure nsf) {
e = nsf;
launcher.getLog().display("receiveReply FAILED due to \"" + e + "\".");
launcher.getLog().display("Pending reply output follows:");
}
String reply = stdoutBuffer.substring(startPos, stdoutBuffer.length());
String[] replyArr = toStringArray(reply);
// Send reply to the logfile. This complements sendCommand(), which does the same.
for (int i = 0; i < replyArr.length; i++) {
launcher.getLog().display("reply[" + i + "]: " + replyArr[i]);
}
if (e != null) throw e;
return replyArr;
}
/**
* Reads JDB_STDOUT_FILE file until prompt is found in the stdoutBuffer.
*
* @param startPos start position for search in stdoutBuffer.
* @param compoundPromptOnly search for compound prompt only.
* @throws Failure if prompt is not encountered during WaitTime.
* @return number of prompt instances really found.
*/
public int waitForPrompt(int startPos, boolean compoundPromptOnly) {
return waitForPrompt(startPos, compoundPromptOnly, 1);
}
/**
* Reads JDB_STDOUT_FILE file until prompt is found in the stdoutBuffer
* count times.
*
* @param startPos start position for search in stdoutBuffer.
* @param compoundPromptOnly search for compound prompt only.
* @throws Failure if prompt is not encountered count times during WaitTime.
* @return number of prompt instances actually found
*
* @see #setCompoundPromptIdent(String)
*/
public int waitForPrompt(int startPos, boolean compoundPromptOnly, int count) {
long delta = 200; // time in milliseconds to wait at every iteration.
long total = 0; // total time has waited.
long max = getLauncher().getJdbArgumentHandler().getWaitTime() * 60 * 1000; // maximum time to wait.
if (count <= 0) {
throw new TestBug("Wrong number of prompts count in Jdb.waitForPrompt(): " + count);
}
Object dummy = new Object();
while ((total += delta) <= max) {
int found = 0;
// check if compound prompt is found
{
found = findPrompt(stdoutBuffer, true, startPos);
if (found >= count) {
return found;
}
}
// check also if simple prompt is found
if (!compoundPromptOnly) {
found += findPrompt(stdoutBuffer, false, startPos);
if (found >= count) {
return found;
}
}
// exit loop when a debugged application exited
if (stdoutBuffer.indexOf(APPLICATION_EXIT) >= 0 || stdoutBuffer.indexOf(APPLICATION_DISCONNECTED) >= 0) {
return found;
} else if (startPos > 0 && !jdbStdoutReader.isAlive()) {
return found;
}
// sleep for awhile
synchronized(dummy) {
try {
dummy.wait(delta);
} catch (InterruptedException ie) {
ie.printStackTrace(getLauncher().getLog().getOutStream());
throw new Failure("Caught interrupted exception while waiting for jdb prompt:\n\t" + ie);
}
}
}
Pattern debuggeeExceptionPattern = Pattern.compile("Exception occurred: (?startPos
.
* The possible prompt kinds are simple prompt "> " and compound prompt,
* that looks like '.*\[[0-9]*\] ' regexp on a single line.
* For example, 'main[1] ' (see setCompoundPromptIdent(String)).
*
* In order to make compatible with jdk prior to 1.4.0 avoid using
* java.util.regex classes.
*
* @return number of prompt instances found
*
* @see #setCompoundPromptIdent(String)
*/
int findPrompt(StringBuffer lines, boolean compoundPromptOnly, int startPos) {
final String nameDelimiters = "-_";
int noPrompt = -1; // prompt is not found;
int simplePrompt = 1;
int complexPrompt = 2;
int length = lines.length();
int found = 0;
// search for simple prompt
if (!compoundPromptOnly) {
int promptLength = SIMPLE_PROMPT.length();
for (int pos = startPos; pos < length; ) {
pos = lines.indexOf(SIMPLE_PROMPT, pos);
if (pos < 0) break;
found++;
pos += promptLength;
}
return found;
}
// search for compound prompt
StringBuffer prompt = new StringBuffer(100);
searching:
for (int pos = startPos; pos < length; ) {
// skip each simbol not suitable for prompt begin
if (!Character.isLetterOrDigit(lines.charAt(pos))) {
pos++;
continue searching;
}
// check for compound prompt
prompt.setLength(0);
// read name (letters or digits or delimiters)
while (nameDelimiters.indexOf(lines.charAt(pos)) > 0
|| Character.isLetterOrDigit(lines.charAt(pos))
|| lines.charAt(pos) == '-'
|| lines.charAt(pos) == '_') {
prompt.append(lines.charAt(pos++));
if (pos >= length) {
break searching;
}
}
// read opening '['
if (lines.charAt(pos) != '[') {
continue searching;
}
prompt.append(lines.charAt(pos++));
if (pos >= length) {
break searching;
}
// read number (digits)
if (!Character.isDigit(lines.charAt(pos))){
continue searching;
}
while (Character.isDigit(lines.charAt(pos))) {
prompt.append(lines.charAt(pos++));
if (pos >= length) {
break searching;
}
}
// read closing ']'
if (lines.charAt(pos) != ']') {
continue searching;
}
prompt.append(lines.charAt(pos++));
if (pos >= length) {
break searching;
}
// read last ' '
if (lines.charAt(pos) != ' ') {
continue searching;
}
prompt.append(lines.charAt(pos++));
// check if not particular ident found
if (compoundPromptIdent != null
&& !prompt.toString().startsWith(compoundPromptIdent + "[")) {
continue searching;
}
// compound prompt found
found++;
}
return found;
}
/**
* Splits string which may include line separators to string array.
*
*/
public static String[] toStringArray (String string) {
Vector