From a69b4955f0188da59cba527c6cae2b899c8cc4ff Mon Sep 17 00:00:00 2001 From: Pawel Piech Date: Tue, 10 Jun 2008 16:33:27 +0000 Subject: [PATCH] [236461] - [pda] Port PDA Virtual Machine implementation to Java --- .../org.eclipse.dd.examples.pda/.classpath | 1 + .../org.eclipse.dd.examples.pda/pdavm/pda.pl | 673 --------------- .../dd/examples/pdavm/PDAVirtualMachine.java | 809 ++++++++++++++++++ .../pdavm/tests/vmtests.pl | 448 ---------- .../pda/launch/PDALaunchDelegate.java | 36 +- .../dd/tests/pda/service/command/Test2.java | 6 +- .../dd/tests/pda/service/command/Test6.java | 6 +- .../eclipse/dd/tests/pda/util/Launching.java | 37 +- 8 files changed, 846 insertions(+), 1170 deletions(-) delete mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl create mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java delete mode 100644 plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl diff --git a/plugins/org.eclipse.dd.examples.pda/.classpath b/plugins/org.eclipse.dd.examples.pda/.classpath index 304e86186aa..8fe3727bbf5 100644 --- a/plugins/org.eclipse.dd.examples.pda/.classpath +++ b/plugins/org.eclipse.dd.examples.pda/.classpath @@ -1,6 +1,7 @@ + diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl b/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl deleted file mode 100644 index 897ff650fba..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/pdavm/pda.pl +++ /dev/null @@ -1,673 +0,0 @@ -#!perl.exe - -use strict; -use warnings; -use IO::Socket; - -##################################################################### -# Copyright (c) 2005 IBM Corporation and others. -# 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: -# Bjorn Freeman-Benson - initial API and implementation -##################################################################### - -##################################################################### -# # -# I N I T I A L I Z A T I O N A N D V A R I A B L E S # -# # -##################################################################### -# -# The push down automata stack (the data stack) -# -my @stack; -# -# Load all the code into memory -# The code is stored as an array of strings, each line of -# the source file being one entry in the array. -# -my $filename = shift; -open INFILE, $filename or die $!; -my @code = ; -close INFILE; - -my %labels; -sub map_labels { - # - # A mapping of labels to indicies in the code array - # - %labels = ( ); - my $idx = 0; - while( $idx <= $#code ) { - if( length $code[$idx] > 0 ) { - $code[$idx] =~ /^\s*(.+?)\s*$/; - $code[$idx] = $1; - $labels{$1} = $idx if( $code[$idx] =~ /^:(\S+)/ ); - } else { - $code[$idx] = "\n"; - } - $idx ++; - } -} -map_labels(); -# -# The stack of stack frames (the control stack) -# Each stack frame is a mapping of variable names to values. -# There are a number of special variable names: -# _pc_ is the current program counter in the frame -# the pc points to the next instruction to be executed -# _func_ is the name of the function in this frame -# -my @frames; -my $currentframe; -$currentframe = { - _pc_ => 0, - _func_ => 'main' - }; - -# -# The command line argument to start a debug session. -# -my $debugflag = shift; -# -# The port to listen for debug commands on -# and the port to send debug events to -# -my $debugport; -my $debugport2; -# -# The socket to listen for debug commands on -# and the socket to send debug events on -# -my $debugsock; -my $debugsock2; -# -# An input buffer -# -my $debugbuf; -# -# Breakpoint array -# breakpoints are stored as a boolean for each line of code -# if the boolean is true, there is a breakpoint on that line -# -my @breakpoints; -# -# Mapping of debugger commands to functions that evaluate them -# -my %debug_commands = ( - clear => \&debug_clear_breakpoint, - data => \&debug_data, - drop => \&debug_drop_frame, - eval => \&debug_eval, - eventstop => \&debug_event_stop, - exit => \&debug_exit, - popdata => \&debug_pop, - pushdata => \&debug_push, - resume => \&debug_resume, - set => \&debug_set_breakpoint, - setdata => \&debug_set_data, - setvar => \&debug_set_variable, - stack => \&debug_stack, - step => \&debug_step, - stepreturn => \&debug_step_return, - suspend => \&debug_suspend, - var => \&debug_var, - watch => \&debug_watch -); - -# -# The run flag is true if the VM is running. -# If the run flag is false, the VM exits the -# next time the main instruction loop runs. -# -my $run = 1; -# -# The suspend flag is true if the VM should suspend -# running the program and just listen for debug commands. -# -my $suspend = 0; -my $started = 1; -$suspend = "client" if( $debugflag ); -# -# The step flag is used to control single-stepping. -# See the implementation of the "step" debug command. -# The stepreturn flag is used to control step-return. -# The eventstops table holds which events cause suspends and which do not. -# The watchpoints table holds watchpoint information. -# variablename_stackframedepth => N -# N = 0 is no watch -# N = 1 is read watch -# N = 2 is write watch -# N = 3 is both, etc. -# -my $step = 0; -my $stepreturn = 0; -my %eventstops = ( "unimpinstr" => 0, - "nosuchlabel" => 0, - ); -my %watchpoints = ( ); - -# -# Mapping of the names of the instructions to the functions that evaluate them -# -my %instructions = ( - add => \&add, - branch_not_zero => \&branch_not_zero, - call => \&call, - dec => \&dec, - dup => \&dup, - halt => \&halt, - output => \&output, - pop => \&ipop, - push => \&ipush, - return => \&ireturn, - var => \&var, - xyzzy => \&internal_end_eval, -); - -##################################################################### -# # -# M A I N I N T E R P R E T E R # -# # -##################################################################### -# -# Open a debug session if the command line argument is given. -# -start_debugger(); -send_debug_event( "started", 0 ); -debug_ui() if( $suspend ); -# -# The main run loop -# -while( $run ) { - check_for_breakpoint(); - debug_ui() if( $suspend ); - yield_to_debug(); - my $instruction = fetch_instruction(); - increment_pc(); - do_one_instruction($instruction); - if( $$currentframe{_pc_} > $#code ) { - $run = 0; - } elsif( $stepreturn ) { - $instruction = fetch_instruction(); - $suspend = "step" if( is_return_instruction($instruction) ); - } -} -send_debug_event( "terminated", 0 ); - -sub fetch_instruction { - my $pc = $$currentframe{_pc_}; - my $theinstruction = $code[$pc]; - return $theinstruction; -} -sub is_return_instruction { - my $theinstruction = shift; - if( $theinstruction =~ /^:/ ) { - return 0; - } elsif( $theinstruction =~ /^#/ ) { - return 0; - } else { - $theinstruction =~ /^(\S+)\s*(.*)/; - return $1 eq "return"; - } -} -sub increment_pc { - my $pc = $$currentframe{_pc_}; - $pc++; - $$currentframe{_pc_} = $pc; -} -sub decrement_pc { - my $pc = $$currentframe{_pc_}; - $pc--; - $$currentframe{_pc_} = $pc; -} -sub do_one_instruction { - my $theinstruction = shift; - if( $theinstruction =~ /^:/ ) { - # label - $suspend = "step" if( $step ); - } elsif( $theinstruction =~ /^#/ ) { - # comment - } else { - $theinstruction =~ /^(\S+)\s*(.*)/; - my $op = $1; - my $instr = $instructions{$op}; - if( $instr ) { - &$instr( $theinstruction, $2 ); - $suspend = "step" if( $step ); - } else { - send_debug_event( "unimplemented instruction $op", 1 ); - if( $eventstops{"unimpinstr"} ) { - $suspend = "event unimpinstr"; - decrement_pc(); - } - } - } -} - -##################################################################### -# # -# I N S T R U C T I O N S # -# # -##################################################################### -sub add { - my $val1 = pop @stack; - my $val2 = pop @stack; - my $val = $val1 + $val2; - push @stack, $val; -} - -sub branch_not_zero { - my $val = pop @stack; - if( $val ) { - shift; - my $label = shift; - my $dest = $labels{$label}; - if( !defined $dest ) { - send_debug_event( "no such label $label", 1 ); - if( $eventstops{"nosuchlabel"} ) { - $suspend = "event nosuchlabel"; - push @stack, $val; - decrement_pc(); - } - } else { - $$currentframe{_pc_} = $dest; - } - } -} - -sub call { - shift; - my $label = shift; - my $dest = $labels{$label}; - if( !defined $dest ) { - send_debug_event( "no such label $label", 1 ); - if( $eventstops{"nosuchlabel"} ) { - $suspend = "event nosuchlabel"; - decrement_pc(); - } - } else { - push @frames, $currentframe; - $currentframe = { - _pc_ => $dest, - _func_ => $label - }; - } -} - -sub dec { - my $val = pop @stack; - $val--; - push @stack, $val; -} - -sub dup { - my $val = pop @stack; - push @stack, $val; - push @stack, $val; -} - -sub halt { - $run = 0; -} - -sub output { - my $val = pop @stack; - print "$val\n"; -} - -sub ipop { - shift; - my $arg = shift; - if( $arg =~ /^\$(.*)/ ) { - $$currentframe{$1} = pop @stack; - my $key = "$$currentframe{_func_}\:\:$1"; - if( defined $watchpoints{$key} ) { - if( $watchpoints{$key} & 2 ) { - $suspend = "watch write $key"; - } - } - } else { - pop @stack; - } -} - -sub ipush { - shift; - my $arg = shift; - if( $arg =~ /^\$(.*)/ ) { - my $val = $$currentframe{$1}; - push @stack, $val; - my $key = "$$currentframe{_func_}\:\:$1"; - if( defined $watchpoints{$key} ) { - if( $watchpoints{$key} & 1 ) { - $suspend = "watch read $key"; - } - } - } else { - push @stack, $arg; - } -} - -sub ireturn { - $currentframe = pop @frames; -} - -sub var { - shift; - my $name = shift; - $$currentframe{$name} = 0; -} - -##################################################################### -# # -# D E B U G G E R I N T E R F A C E # -# # -##################################################################### - -sub check_for_breakpoint { - if( $debugflag ) { - my $pc = $$currentframe{_pc_}; - if( $breakpoints[$pc] ) { - $suspend = "breakpoint $pc" unless $suspend eq "eval"; - } - } -} -# -# For each instruction, we check the debug co-routine for -# control input. If there is input, we process it. -# -sub yield_to_debug { - if( $debugflag ) { - my $bytes_to_read = 1024; - my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); - if( defined($bytes_read) ) { - #print "read $bytes_to_read\n"; - my $rin = ''; - my $win = ''; - my $ein = ''; - vec($rin,fileno($debugsock),1) = 1; - $ein = $rin | $win; - my $debugline = $debugbuf; - while( !($debugline =~ /\n/) ) { - select($rin, undef, undef, undef); - my $bytes_to_read = 1024; - my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); - $debugline .= $debugbuf; - } - #print "read: $debugline"; - process_debug_command($debugline); - $debugline = ''; - } else { - # no bytes read - } - } -} - -# -# If the execution is suspended, then we go into the debug -# ui loop, reading and processing instructions. -# -sub debug_ui { - return unless( $suspend ); - my $pc = $$currentframe{_pc_}; - if (!$started) { - send_debug_event( "suspended $suspend", 0 ); - } else { - $started = 0; - } - $step = 0; - $stepreturn = 0; - my $rin = ''; - my $win = ''; - my $ein = ''; - vec($rin,fileno($debugsock),1) = 1; - $ein = $rin | $win; - my $debugline = ''; - while( $suspend ) { - select($rin, undef, undef, undef); - my $bytes_to_read = 1024; - my $bytes_read = sysread($debugsock, $debugbuf, $bytes_to_read); - $debugline .= $debugbuf; - if( $debugline =~ /\n/ ) { - #print "read: $debugline"; - process_debug_command($debugline); - $debugline = ''; - } - } - send_debug_event( "resumed step", 0 ) if( $step ); - send_debug_event( "resumed client", 0 ) unless( $step ); -} - -sub process_debug_command { - my $line = shift; - return if( length $line < 2 ); - my @words = split /\s/, $line; - my $command = lc($words[0]); - my $dfunc = $debug_commands{$words[0]}; - if( $dfunc ) { - &$dfunc( @words ); - } -} - -sub debug_clear_breakpoint { - shift; - my $line = shift; - $breakpoints[$line] = 0; - print $debugsock "ok\n"; -} -my @saved_code; -my %saved_labels; -my $saved_pc; -sub debug_eval { - shift; - my $code = shift; - my @lines = split /\|/, $code; - my $newpc = scalar @code; - @saved_code = @code; - %saved_labels = %labels; - foreach my $line ( @lines ) { - $line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; - push @code, $line; - } - push @code, "xyzzy"; - map_labels(); - $saved_pc = $$currentframe{_pc_}; - $$currentframe{_pc_} = $newpc; - print $debugsock "ok\n"; - $suspend = 0; -} -sub internal_end_eval { - my $result = pop @stack; - @code = @saved_code; - %labels = %saved_labels; - $$currentframe{_pc_} = $saved_pc; - send_debug_event( "evalresult $result", 0 ); - $suspend = "eval"; -} - -sub debug_data { - my $result = ''; - foreach my $d ( @stack ) { - $result .= $d . '|'; - } - print $debugsock "$result\n"; -} -sub debug_drop_frame { - ireturn(); - decrement_pc(); - print $debugsock "ok\n"; - send_debug_event( "resumed drop", 0 ); - send_debug_event( "suspended drop", 0 ); -} -sub debug_event_stop { - shift; - my $event = shift; - my $bool = shift; - $eventstops{$event} = $bool; - print $debugsock "ok\n"; -} -sub debug_exit { - print $debugsock "ok\n"; - send_debug_event( "terminated", 0 ); - exit 0; -} -sub debug_pop { - pop @stack; - print $debugsock "ok\n"; -} -sub debug_push { - shift; - my $value = shift; - push @stack, $value; - print $debugsock "ok\n"; -} -sub debug_resume { - $suspend = 0; - print $debugsock "ok\n"; -} -sub debug_set_breakpoint { - shift; - my $line = shift; - $breakpoints[$line] = 1; - print $debugsock "ok\n"; -} -sub debug_set_data { - shift; - my $offset = shift; - my $value = shift; - $stack[$offset] = $value; - print $debugsock "ok\n"; -} -sub debug_set_variable { - shift; - my $sfnumber = shift; - my $var = shift; - my $value = shift; - if( $sfnumber > $#frames ) { - $$currentframe{$var} = $value; - } else { - my $theframe = $frames[$sfnumber]; - $$theframe{$var} = $value; - } - print $debugsock "ok\n"; -} -sub debug_stack { - my $result = ''; - foreach my $frame ( @frames ) { - $result .= print_frame($frame); - $result .= '#'; - } - $result .= print_frame($currentframe); - print $debugsock "$result\n"; -} -sub debug_step { - # set suspend to 0 to allow the debug loop to exit back to - # the instruction loop and thus run an instruction. However, - # we want to come back to the debug loop right away, so the - # step flag is set to true which will cause the suspend flag - # to get set to true when we get to the next instruction. - $step = 1; - $suspend = 0; - print $debugsock "ok\n"; -} -sub debug_step_return { - $stepreturn = 1; - $suspend = 0; - print $debugsock "ok\n"; -} -sub debug_suspend { - $suspend = "client"; - print $debugsock "ok\n"; -} -sub debug_var { - shift; - my $sfnumber = shift; - my $var = shift; - if( $sfnumber > $#frames ) { - print $debugsock "$$currentframe{$var}\n"; - } else { - my $theframe = $frames[$sfnumber]; - print $debugsock "$$theframe{$var}\n"; - } -} -sub debug_watch { - shift; - my $key = shift; - my $value = shift; - $watchpoints{$key} = $value; - print $debugsock "ok\n"; -} -# -# Some event has happened so notify the debugger. -# If there is no debugger, we may still want to report the -# event (such as if it is an error). -# -sub send_debug_event { - my $event = shift; - if( $debugflag ) { - print $debugsock2 "$event\n"; - } else { - my $use_stderr = shift; - print "Error: $event\n" if $use_stderr; - } -} -# -# The stack frame output is: -# frame # frame # frame ... -# where each frame is: -# filename | line number | function name | var | var | var | var ... -# -sub print_frame { - my $frame = shift; - my $result = $filename; - $result .= '|' . $$frame{_pc_}; - $result .= '|' . $$frame{_func_}; - for my $var ( keys %$frame ) { - $result .= '|' . $var unless( substr($var,0,1) eq '_'); - } - return $result; -} - -sub start_debugger { - if( defined($debugflag) ) { - if( $debugflag eq "-debug" ) { - { # make STDOUT unbuffered - my $ofh = select STDOUT; - $| = 1; - select $ofh; - } - $debugflag = 1; - $debugport = shift @ARGV; - $debugport2 = shift @ARGV; - print "-debug $debugport $debugport2\n"; - - my $mainsock = new IO::Socket::INET (LocalHost => '127.0.0.1', - LocalPort => $debugport, - Listen => 1, - Proto => 'tcp', - Reuse => 1, - ); - $debugsock = $mainsock->accept(); - my $set_it = "1"; - my $ioctl_val = 0x80000000 | (4 << 16) | (ord('f') << 8) | 126; - ioctl($debugsock, $ioctl_val, $set_it); #or die "couldn't set nonblocking: $^E"; - $debugsock->blocking(0); - - my $mainsock2 = new IO::Socket::INET (LocalHost => '127.0.0.1', - LocalPort => $debugport2, - Listen => 1, - Proto => 'tcp', - Reuse => 1, - ); - $debugsock2 = $mainsock2->accept(); - - print "debug connection accepted\n"; - } else { - $debugflag = 0; - } - } -} diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java b/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java new file mode 100644 index 00000000000..d371f00c686 --- /dev/null +++ b/plugins/org.eclipse.dd.examples.pda/pdavm/src/org/eclipse/dd/examples/pdavm/PDAVirtualMachine.java @@ -0,0 +1,809 @@ +/******************************************************************************* + * Copyright (c) 2008 Wind River Systems and others. + * 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: + * Wind River Systems - initial API and implementation + *******************************************************************************/ +package org.eclipse.dd.examples.pdavm; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringWriter; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + */ +@SuppressWarnings("serial") +public class PDAVirtualMachine { + + class Stack extends LinkedList { + public Object pop() { + return isEmpty() ? 0 : remove(size() - 1); + } + + public void push(Object value) { + add(value); + } + } + + class Args { + private final String[] fArgs; + int next = 0; + Args(String[] args) { + fArgs = args; + } + + String getNextStringArg() { + if (fArgs.length > next) { + return fArgs[next++]; + } + return ""; + } + + int getNextIntArg() { + String arg = getNextStringArg(); + try { + return Integer.parseInt(arg); + } catch (NumberFormatException e) {} + return 0; + } + + Object getNextIntOrStringArg() { + String arg = getNextStringArg(); + try { + return Integer.parseInt(arg); + } catch (NumberFormatException e) {} + return arg; + } + } + + /** The push down automata data stack (the data stack). */ + private final Stack fStack = new Stack(); + + /** + * The code is stored as an array of strings, each line of + * the source file being one entry in the array. + */ + private String[] fCode; + + /** A mapping of labels to indicies in the code array */ + private Map fLabels = new HashMap(); + + /** Each stack frame is a mapping of variable names to values. */ + class Frame extends LinkedHashMap { + /** + * The name of the function in this frame + */ + final String fFunction; + + /** + * The current program counter in the frame + * the pc points to the next instruction to be executed + */ + int fPC; + + public Frame(String function, int pc) { + fFunction = function; + fPC = pc; + } + } + + /** The stack of stack frames (the control stack) */ + private final List fFrames = new LinkedList(); + + /** Current stack frame (not includced in fFrames) */ + private Frame fCurrentFrame = new Frame("main", 0); + + /** + * Breakpoints are stored as a boolean for each line of code + * if the boolean is true, there is a breakpoint on that line + */ + private final Map fBreakpoints = new HashMap(); + + /** + * The run flag is true if the VM is running. + * If the run flag is false, the VM exits the + * next time the main instruction loop runs. + */ + private boolean fRun = true; + + /** + * The suspend flag is true if the VM should suspend + * running the program and just listen for debug commands. + */ + private String fSuspend; + + /** Flag indicating whether the debugger is performing a step. */ + private boolean fStep = false; + + /** Flag indicating whether the debugger is performing a step return */ + private boolean fStepReturn = false; + + /** Flag indicating whether the started event was sent. */ + private boolean fStarted = true; + + /** Name of the pda program being debugged */ + private final String fFilename; + + /**The command line argument to start a debug session. */ + private final boolean fDebug; + + /** The port to listen for debug commands on */ + private final int fCommandPort; + + /** Command socket for receiving debug commands and sending command responses */ + private Socket fCommandSocket; + + /** Command socket reader */ + private BufferedReader fCommandReceiveStream; + + /** Command socket write stream. */ + private OutputStream fCommandResponseStream; + + /** The port to send debug events to */ + private final int fEventPort; + + /** Event socket */ + private Socket fEventSocket; + + /** Event socket and write stream. */ + private OutputStream fEventStream; + + /** The eventstops table holds which events cause suspends and which do not. */ + private final Map fEventStops = new HashMap(); + { + fEventStops.put("unimpinstr", false); + fEventStops.put("nosuchlabel", false); + } + + /** + * The watchpoints table holds watchpoint information. + * variablename_stackframedepth => N + * N = 0 is no watch + * N = 1 is read watch + * N = 2 is write watch + * N = 3 is both, etc. + */ + private final Map fWatchpoints = new HashMap(); + + public String[] fSavedCode; + public Map fSavedLables; + public int fSavedPC; + + public static void main(String[] args) { + String programFile = args.length >= 1 ? args[0] : null; + if (programFile == null) { + System.err.println("Error: No program specified"); + return; + } + + String debugFlag = args.length >= 2 ? args[1] : ""; + boolean debug = "-debug".equals(debugFlag); + int commandPort = 0; + int eventPort = 0; + + if (debug) { + String commandPortStr = args.length >= 3 ? args[2] : ""; + try { + commandPort = Integer.parseInt(commandPortStr); + } catch (NumberFormatException e) { + System.err.println("Error: Invalid command port"); + return; + } + + String eventPortStr = args.length >= 4 ? args[3] : ""; + try { + eventPort = Integer.parseInt(eventPortStr); + } catch (NumberFormatException e) { + System.err.println("Error: Invalid event port"); + return; + } + } + + PDAVirtualMachine pdaVM = null; + try { + pdaVM = new PDAVirtualMachine(programFile, debug, commandPort, eventPort); + pdaVM.startDebugger(); + } catch (IOException e) { + System.err.println("Error: " + e.toString()); + return; + } + pdaVM.run(); + } + + public PDAVirtualMachine(String inputFile, boolean debug, int commandPort, int eventPort) throws IOException{ + fFilename = inputFile; + + // Load all the code into memory + FileReader fileReader = new FileReader(inputFile); + StringWriter stringWriter = new StringWriter(); + List code = new LinkedList(); + int c = fileReader.read(); + while (c != -1) { + if (c == '\n') { + code.add(stringWriter.toString().trim()); + stringWriter = new StringWriter(); + } else { + stringWriter.write(c); + } + c = fileReader.read(); + } + code.add(stringWriter.toString().trim()); + fCode = code.toArray(new String[code.size()]); + + mapLabels(); + + fDebug = debug; + fCommandPort = commandPort; + fEventPort = eventPort; + if (fDebug) { + fSuspend = "client"; + } + } + + /** + * Initializes the labels map + */ + private void mapLabels() { + fLabels = new HashMap(); + for (int i = 0; i < fCode.length; i++) { + if (fCode[i].length() != 0 && fCode[i].charAt(0) == ':') { + fLabels.put(fCode[i].substring(1), i); + } + } + + } + + private void sendCommandResponse(String response) { + try { + fCommandResponseStream.write(response.getBytes()); + fCommandResponseStream.flush(); + } catch (IOException e) {} + } + + private void sendDebugEvent(String event, boolean error) { + if (fDebug) { + try { + fEventStream.write(event.getBytes()); + fEventStream.write('\n'); + fEventStream.flush(); + } catch (IOException e) { + System.err.println("Error: " + e); + fRun = false; + } + } else if (error) { + System.err.println("Error: " + event); + } + } + + private void startDebugger() throws IOException { + if (fDebug) { + System.out.println("-debug " + fCommandPort + " " + fEventPort); + } + + ServerSocket commandServerSocket = new ServerSocket(fCommandPort); + fCommandSocket = commandServerSocket.accept(); + fCommandReceiveStream = new BufferedReader(new InputStreamReader(fCommandSocket.getInputStream())); + fCommandResponseStream = new PrintStream(fCommandSocket.getOutputStream()); + commandServerSocket.close(); + + ServerSocket eventServerSocket = new ServerSocket(fEventPort); + fEventSocket = eventServerSocket.accept(); + fEventStream = new PrintStream(fEventSocket.getOutputStream()); + eventServerSocket.close(); + + System.out.println("debug connection accepted"); + + fSuspend = "client"; + sendDebugEvent("started", false); + } + + public void run() { + while (fRun) { + checkForBreakpoint(); + if (fSuspend != null) { + debugUI(); + } + yieldToDebug(); + String instruction = fCode[fCurrentFrame.fPC]; + fCurrentFrame.fPC++; + doOneInstruction(instruction); + if (fCurrentFrame.fPC > fCode.length) { + fRun = false; + } else if (fStepReturn) { + instruction = fCode[fCurrentFrame.fPC]; + if ("return".equals(instruction)) { + fSuspend = "step"; + } + } + } + sendDebugEvent("terminated", false); + if (fDebug) { + try { + fCommandReceiveStream.close(); + fCommandResponseStream.close(); + fCommandSocket.close(); + fEventStream.close(); + fEventSocket.close(); + } catch (IOException e) { + System.out.println("Error: " + e); + } + } + + } + + private void doOneInstruction(String instr) { + if (instr.startsWith(":")) { + // label + if (fStep) { + fSuspend = "step"; + } + } else if (instr.startsWith("#")) { + // comment + } else { + StringTokenizer tokenizer = new StringTokenizer(instr); + String op = tokenizer.nextToken(); + List tokens = new LinkedList(); + while (tokenizer.hasMoreTokens()) { + tokens.add(tokenizer.nextToken()); + } + Args args = new Args(tokens.toArray(new String[tokens.size()])); + + boolean opValid = true; + if (op.equals("add")) iAdd(args); + else if (op.equals("branch_not_zero")) iBranchNotZero(args); + else if (op.equals("call")) iCall(args); + else if (op.equals("dec")) iDec(args); + else if (op.equals("dup")) iDup(args); + else if (op.equals("halt")) iHalt(args); + else if (op.equals("output")) iOutput(args); + else if (op.equals("pop")) iPop(args); + else if (op.equals("push")) iPush(args); + else if (op.equals("return")) iReturn(args); + else if (op.equals("var")) iVar(args); + else if (op.equals("xyzzy")) iInternalEndEval(args); + else { + opValid = false; + } + + if (!opValid) { + sendDebugEvent("unimplemented instruction " + op, true); + if (fEventStops.get("unimpinstr")) { + fSuspend = "event unimpinstr"; + fCurrentFrame.fPC--; + } + } else if (fStep) { + fSuspend = "step"; + } + } + } + + private void checkForBreakpoint() { + if (fDebug) { + int pc = fCurrentFrame.fPC; + if (!"eval".equals(fSuspend) && fBreakpoints.containsKey(pc) && fBreakpoints.get(pc)) { + fSuspend = "breakpoint " + pc; + } + } + } + + /** + * For each instruction, we check the debug co-routine for + * control input. If there is input, we process it. + */ + private void yieldToDebug() { + if (fDebug) { + String line = ""; + try { + if (fCommandReceiveStream.ready()) { + line = fCommandReceiveStream.readLine(); + processDebugCommand(line); + } + } catch (IOException e) { + System.err.println("Error: " + e); + fRun = false; + return; + } + } + } + + private void debugUI() { + if (fSuspend == null) { + return; + } + + if (!fStarted) { + sendDebugEvent("suspended " + fSuspend, false); + } else { + fStarted = false; + } + + fStep = false; + fStepReturn = false; + + while (fSuspend != null) { + String line = ""; + try { + line = fCommandReceiveStream.readLine(); + } catch (IOException e) { + System.err.println("Error: " + e); + fRun = false; + return; + } + processDebugCommand(line); + } + if (fStep) { + sendDebugEvent("resumed step", false); + } else { + sendDebugEvent("resumed client", false); + } + } + + private void processDebugCommand(String line) { + StringTokenizer tokenizer = new StringTokenizer(line.trim()); + if (line.length() == 0) { + return; + } + + String command = tokenizer.nextToken(); + List tokens = new LinkedList(); + while (tokenizer.hasMoreTokens()) { + tokens.add(tokenizer.nextToken()); + } + Args args = new Args(tokens.toArray(new String[tokens.size()])); + + if ("clear".equals(command)) debugClearBreakpoint(args); + else if ("data".equals(command)) debugData(); + else if ("drop".equals(command)) debugDropFrame(); + else if ("eval".equals(command)) debugEval(args); + else if ("eventstop".equals(command)) debugEventStop(args); + else if ("exit".equals(command)) debugExit(); + else if ("popdata".equals(command)) debugPop(); + else if ("pushdata".equals(command)) debugPush(args); + else if ("resume".equals(command)) debugResume(); + else if ("set".equals(command)) debugSetBreakpoint(args); + else if ("setdata".equals(command)) debugSetData(args); + else if ("setvar".equals(command)) debugSetVariable(args); + else if ("stack".equals(command)) debugStack(); + else if ("step".equals(command)) debugStep(); + else if ("stepreturn".equals(command)) debugStepReturn(); + else if ("suspend".equals(command)) debugSuspend(); + else if ("var".equals(command)) debugVar(args); + else if ("watch".equals(command)) debugWatch(args); + } + + private void debugClearBreakpoint(Args args) { + int line = args.getNextIntArg(); + + fBreakpoints.put(line, false); + sendCommandResponse("ok\n"); + } + + private static Pattern fPackPattern = Pattern.compile("%([a-fA-F0-9][a-fA-F0-9])"); + private void debugEval(Args args) { + + StringTokenizer tokenizer = new StringTokenizer(args.getNextStringArg(), "|"); + tokenizer.countTokens(); + + fSavedCode = fCode; + int numEvalLines = tokenizer.countTokens(); + fCode = new String[fSavedCode.length + numEvalLines + 1]; + System.arraycopy(fSavedCode, 0, fCode, 0, fSavedCode.length); + for (int i = 0; i < numEvalLines; i++) { + String line = tokenizer.nextToken(); + StringBuffer lineBuf = new StringBuffer(line.length()); + Matcher matcher = fPackPattern.matcher(line); + int lastMatchEnd = 0; + while (matcher.find()) { + lineBuf.append(line.substring(lastMatchEnd, matcher.start())); + String charCode = line.substring(matcher.start() + 1, matcher.start() + 3); + try { + lineBuf.append((char)Integer.parseInt(charCode, 16)); + } catch (NumberFormatException e) {} + lastMatchEnd = matcher.end(); + } + if (lastMatchEnd < line.length()) { + lineBuf.append(line.substring(lastMatchEnd)); + } + fCode[fSavedCode.length + i] = lineBuf.toString(); + } + fCode[fSavedCode.length + numEvalLines] = "xyzzy"; + mapLabels(); + + fSavedPC = fCurrentFrame.fPC; + fCurrentFrame.fPC = fSavedCode.length; + + sendCommandResponse("ok\n"); + + fSuspend = null; + } + + private void debugData() { + StringBuffer result = new StringBuffer(); + for (Object val : fStack) { + result.append(val); + result.append('|'); + } + result.append('\n'); + sendCommandResponse(result.toString()); + } + + private void debugDropFrame() { + if (!fFrames.isEmpty()) { + fCurrentFrame = fFrames.remove(fFrames.size() - 1); + } + fCurrentFrame.fPC--; + sendCommandResponse("ok\n"); + sendDebugEvent( "resumed drop", false ); + sendDebugEvent( "suspended drop", false ); + } + + private void debugEventStop(Args args) { + String event = args.getNextStringArg(); + int stop = args.getNextIntArg(); + fEventStops.put(event, stop > 0); + sendCommandResponse("ok\n"); + } + + private void debugExit() { + sendCommandResponse("ok\n"); + sendDebugEvent( "terminated", false ); + System.exit(0); + } + + private void debugPop() { + fStack.pop(); + sendCommandResponse("ok\n"); + } + + private void debugPush(Args args) { + Object val = args.getNextIntOrStringArg(); + fStack.push(val); + sendCommandResponse("ok\n"); + } + + private void debugResume() { + fSuspend = null; + sendCommandResponse("ok\n"); + } + + private void debugSetBreakpoint(Args args) { + int line = args.getNextIntArg(); + + fBreakpoints.put(line, true); + sendCommandResponse("ok\n"); + } + + private void debugSetData(Args args) { + int offset = args.getNextIntArg(); + Object val = args.getNextIntOrStringArg(); + + if (offset < fStack.size()) { + fStack.set(offset, val); + } else { + fStack.add(0, val); + } + sendCommandResponse("ok\n"); + } + + private void debugSetVariable(Args args) { + int sfnumber = args.getNextIntArg(); + String var = args.getNextStringArg(); + Object val = args.getNextIntOrStringArg(); + + if (sfnumber > fFrames.size()) { + fCurrentFrame.put(var, val); + } else { + fFrames.get(sfnumber).put(var, val); + } + sendCommandResponse("ok\n"); + } + + private void debugStack() { + StringBuffer result = new StringBuffer(); + for (Frame frame : fFrames) { + result.append(printFrame(frame)); + result.append('#'); + } + result.append(printFrame(fCurrentFrame)); + result.append('\n'); + sendCommandResponse(result.toString()); + } + + + /** + * The stack frame output is: + * frame # frame # frame ... + * where each frame is: + * filename | line number | function name | var | var | var | var ... + */ + private String printFrame(Frame frame) { + StringBuffer buf = new StringBuffer(); + buf.append(fFilename); + buf.append('|'); + buf.append(frame.fPC); + buf.append('|'); + buf.append(frame.fFunction); + for (String var : frame.keySet()) { + buf.append('|'); + buf.append(var); + } + return buf.toString(); + } + + private void debugStep() { + // set suspend to 0 to allow the debug loop to exit back to + // the instruction loop and thus run an instruction. However, + // we want to come back to the debug loop right away, so the + // step flag is set to true which will cause the suspend flag + // to get set to true when we get to the next instruction. + fStep = true; + fSuspend = null; + sendCommandResponse("ok\n"); + } + + private void debugStepReturn() { + fStepReturn = true; + fSuspend = null; + sendCommandResponse("ok\n"); + } + + private void debugSuspend() { + fSuspend = "client"; + sendCommandResponse("ok\n"); + } + + private void debugVar(Args args) { + int sfnumber = args.getNextIntArg(); + String var = args.getNextStringArg(); + + if (sfnumber >= fFrames.size()) { + sendCommandResponse(fCurrentFrame.get(var).toString() + "\n"); + } else { + sendCommandResponse(fFrames.get(sfnumber).get(var).toString() + "\n"); + } + } + + private void debugWatch(Args args) { + String funcAndVar = args.getNextStringArg(); + int flags = args.getNextIntArg(); + fWatchpoints.put(funcAndVar, flags); + sendCommandResponse("ok\n"); + } + + private void iAdd(Args args) { + Object val1 = fStack.pop(); + Object val2 = fStack.pop(); + if (val1 instanceof Integer && val2 instanceof Integer) { + int intVal1 = ((Integer)val1).intValue(); + int intVal2 = ((Integer)val2).intValue(); + fStack.push(intVal1 + intVal2); + } else { + fStack.push(-1); + } + } + + private void iBranchNotZero(Args args) { + Object val = fStack.pop(); + if( val instanceof Integer && ((Integer)val).intValue() != 0 ) { + String label = args.getNextStringArg(); + if (fLabels.containsKey(label)) { + fCurrentFrame.fPC = fLabels.get(label); + } else { + sendDebugEvent("no such label " + label, true); + if( fEventStops.get("nosuchlabel") ) { + fSuspend = "event nosuchlabel"; + fStack.push(val); + fCurrentFrame.fPC--; + } + } + } + } + + private void iCall(Args args) { + String label = args.getNextStringArg(); + if (fLabels.containsKey(label)) { + fFrames.add(fCurrentFrame); + fCurrentFrame = new Frame(label, fLabels.get(label)); + } else { + sendDebugEvent("no such label " + label, true); + if( fEventStops.get("nosuchlabel") ) { + fSuspend = "event nosuchlabel"; + fCurrentFrame.fPC--; + } + } + } + + private void iDec(Args args) { + Object val = fStack.pop(); + if (val instanceof Integer) { + val = new Integer( ((Integer)val).intValue() - 1 ); + } + fStack.push(val); + } + + private void iDup(Args args) { + Object val = fStack.pop(); + fStack.push(val); + fStack.push(val); + } + + private void iHalt(Args args) { + fRun = false; + } + + private void iOutput(Args args) { + System.out.println(fStack.pop()); + } + + private void iPop(Args args) { + String arg = args.getNextStringArg(); + if (arg.startsWith("$")) { + String var = arg.substring(1); + fCurrentFrame.put(var, fStack.pop()); + String key = fCurrentFrame.fFunction + "::" + var; + if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 2) != 0) { + fSuspend = "watch write " + key; + } + } else { + fStack.pop(); + } + } + + private void iPush(Args args) { + String arg = args.getNextStringArg(); + if (arg.startsWith("$")) { + String var = arg.substring(1); + Object val = fCurrentFrame.containsKey(var) ? fCurrentFrame.get(var) : ""; + fStack.push(val); + String key = fCurrentFrame.fFunction + "::" + var; + if (fWatchpoints.containsKey(key) && (fWatchpoints.get(key) & 1) != 0) { + fSuspend = "watch read " + key; + } + } else { + Object val = arg; + try { + val = Integer.parseInt(arg); + } catch (NumberFormatException e) {} + fStack.push(val); + } + } + private void iReturn(Args args) { + if (!fFrames.isEmpty()) { + fCurrentFrame = fFrames.remove(fFrames.size() - 1); + } + } + private void iVar(Args args) { + String var = args.getNextStringArg(); + fCurrentFrame.put(var, 0); + } + + private void iInternalEndEval(Args args) { + Object result = fStack.pop(); + fCode = fSavedCode; + fLabels = fSavedLables; + fCurrentFrame.fPC = fSavedPC; + sendDebugEvent("evalresult " + result, false); + fSuspend = "eval"; + } + + +} diff --git a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl b/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl deleted file mode 100644 index 5eff5c103e5..00000000000 --- a/plugins/org.eclipse.dd.examples.pda/pdavm/tests/vmtests.pl +++ /dev/null @@ -1,448 +0,0 @@ -#!perl.exe - -use strict; -use warnings; -use IO::Socket; - -##################################################################### -# Copyright (c) 2004-2005 IBM Corporation and others. -# 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: -# Bjorn Freeman-Benson - initial API and implementation -##################################################################### -# -# This test is designed to run on Windows: -# -# cd c:\eclipse\workspace\org.eclipse.debug.examples.core -# perl pdavm\tests\vmtests.pl -# -# If the tests fail, they often indicate that by hanging in an -# infinite loop. Additionally, the vm under test often becomes -# a 100% CPU usage zombie. Use the task manager to kill them. -# -my $socket1; -my $socket2; - -sub expect_output { - my $expect = shift; - my $line = ; - chomp($line); - return if( $line eq $expect ); - die "expected output: $expect\nSaw output: $line"; -} -sub expect_output_eof { - my $line = ; - return if( !defined $line ); - die "expected: EOF on output"; -} -sub send_command { - my $string = shift; - my $expect = shift; - $expect = "ok" if( !defined $expect ); - #print STDERR "SEND: $string\n"; - print $socket1 "$string\n"; - my $result = <$socket1>; - chomp($result); - #print STDERR "RESULT: $result\n"; - die "sent: $string\nexpected: $expect\nsaw: $result" if( !($result eq $expect) ); -} -sub expect_event { - my $string = shift; - my $event = <$socket2>; - chomp($event); - #print STDERR "EVENT: $event\n"; - die "expected event: $string\nsaw event: $event" if( !($string eq $event) ); -} -sub setup_sockets { - #print STDERR "calling socket 12345\n"; - $socket1 = IO::Socket::INET->new( - Proto => "tcp", - PeerAddr => "localhost", - PeerPort => "12345", - Timeout => 10, - ) - or die "cannot connect to debug socket 12345"; - #print STDERR "calling socket 12346\n"; - $socket2 = IO::Socket::INET->new( - Proto => "tcp", - PeerAddr => "localhost", - PeerPort => "12346", - Timeout => 10, - ) - or die "cannot connect to debug socket 12346"; - #print STDERR "done calling sockets\n"; -} - -sub test2 { - print "test2 (common debug commands)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm/pda.pl pdavm/tests/vmtest2.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("10"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - # test step - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - # test breakpoint - send_command("set 4"); - send_command("data", "6|"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 4"); - # test data stack - send_command("data", "6|7|8|9|"); - send_command("popdata"); - send_command("data", "6|7|8|"); - send_command("pushdata 11"); - send_command("data", "6|7|8|11|"); - send_command("setdata 1 2"); - send_command("data", "6|2|8|11|"); - # test call stack - send_command("set 12"); - send_command("set 19"); - send_command("stepreturn"); - expect_event("resumed client"); - expect_event("suspended breakpoint 12"); - send_command("clear 19"); - send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|12|sub2" ); - send_command("stepreturn"); - expect_event("resumed client"); - expect_event("suspended step"); - send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|18|sub1|m|n#pdavm\\tests\\vmtest2.pda|13|sub2" ); - send_command("stepreturn"); - expect_event("resumed client"); - expect_event("suspended step"); - send_command("stack", "pdavm\\tests\\vmtest2.pda|6|main#pdavm\\tests\\vmtest2.pda|22|sub1|m|n" ); - send_command("set 6"); - send_command("stepreturn"); - expect_event("resumed client"); - expect_event("suspended breakpoint 6"); - # test set and clear - send_command("set 27"); - send_command("set 29"); - send_command("set 33"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 33"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 27"); - send_command("clear 33"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 29"); - # test var and setvar - send_command("set 47"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 47"); - send_command("var 1 b", "4"); - send_command("var 2 b", "2"); - send_command("var 1 a", "0"); - send_command("setvar 1 a 99"); - send_command("data", "6|2|8|11|27|1|4|"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("var 1 a", "99"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("data", "6|2|8|11|27|1|4|99|"); - # test exit - send_command("exit"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test2..SUCCESS\n"; -} - -sub test3 { - print "test3 (uncaught events)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("10"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("resume"); - expect_event("resumed client"); - expect_event("unimplemented instruction foobar"); - expect_event("no such label zippy"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test3..SUCCESS\n"; -} -sub test4 { - print "test4 (caught events)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("10"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("eventstop unimpinstr 1"); - send_command("resume"); - expect_event("resumed client"); - expect_event("unimplemented instruction foobar"); - expect_event("suspended event unimpinstr"); - send_command("eventstop unimpinstr 0"); - send_command("resume"); - expect_event("resumed client"); - expect_event("unimplemented instruction foobar"); - expect_event("no such label zippy"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test4..SUCCESS\n"; -} -sub test5 { - print "test5 (caught events)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest3.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("10"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("eventstop nosuchlabel 1"); - send_command("resume"); - expect_event("resumed client"); - expect_event("unimplemented instruction foobar"); - expect_event("no such label zippy"); - expect_event("suspended event nosuchlabel"); - send_command("eventstop nosuchlabel 0"); - send_command("resume"); - expect_event("resumed client"); - expect_event("no such label zippy"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test5..SUCCESS\n"; -} -sub test6 { - print "test6 (watch points)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("8"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("watch inner::a 1"); - send_command("watch main::a 2"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended watch write main::a"); - send_command("stack", "pdavm\\tests\\vmtest6.pda|4|main|a|b"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended watch read inner::a"); - send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|25|inner|a|c"); - send_command("watch inner::a 0"); - send_command("resume"); - expect_event("resumed client"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test6..SUCCESS\n"; -} -sub test7 { - print "test7 (eval)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest6.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("8"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("set 25"); - send_command("resume"); - expect_event("resumed client"); - expect_event("suspended breakpoint 25"); - # - send_command("eval push%204|push%205|add"); - expect_event("resumed client"); - expect_event("evalresult 9"); - expect_event("suspended eval"); - # - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c"); - send_command("data", "4|4|"); - send_command("eval call%20other"); - expect_event("resumed client"); - expect_event("evalresult 15"); - expect_event("suspended eval"); - send_command("stack", "pdavm\\tests\\vmtest6.pda|10|main|a|b#pdavm\\tests\\vmtest6.pda|26|inner|a|c"); - send_command("data", "4|4|"); - send_command("resume"); - expect_event("resumed client"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test7..SUCCESS\n"; -} -sub test1 { - print "test1 (normal run mode)..\n"; - open PROGRAM_OUTPUT, "perl pdavm/pda.pl samples/example.pda |" or die $!; - expect_output("\"hello\""); - expect_output("\"barfoo\""); - expect_output("\"first\""); - expect_output("\"second\""); - expect_output("12"); - expect_output("11"); - expect_output("10"); - expect_output("\"barfoo\""); - expect_output("\"first\""); - expect_output("\"second\""); - expect_output("\"end\""); - expect_output_eof(); - print "test1..SUCCESS\n"; -} -sub test8 { - print "test8 (drop to frame)..\n"; - - my $kidpid; - die "can't fork: $!" unless defined($kidpid = fork()); - if( $kidpid ) { - #print STDERR "starting program\n"; - open PROGRAM_OUTPUT, "perl pdavm\\pda.pl pdavm\\tests\\vmtest8.pda -debug 12345 12346 |"; - #print STDERR "done starting program\n"; - expect_output("-debug 12345 12346"); - expect_output("debug connection accepted"); - expect_output("1"); - expect_output_eof(); - exit 0; - } else { - setup_sockets(); - expect_event("started"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|12|inner2|c"); - send_command("drop"); - expect_event("suspended drop"); - send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|7|inner|b"); - send_command("step"); - expect_event("resumed step"); - expect_event("suspended step"); - send_command("stack", "pdavm\\tests\\vmtest8.pda|2|main|a#pdavm\\tests\\vmtest8.pda|8|inner|b#pdavm\\tests\\vmtest8.pda|10|inner2"); - send_command("resume"); - expect_event("resumed client"); - expect_event("terminated"); - } - #print STDERR "waiting for child\n"; - wait(); - #print STDERR "child joined\n"; - close PROGRAM_OUTPUT; - print "test8..SUCCESS\n"; -} - -# -# Run the tests -# -test1(); -test2(); -test3(); -test4(); -test5(); -test6(); -test7(); -test8(); -print "All tests complete\n"; diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java index 97fcc746af1..d9e988b41f9 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/examples/pda/launch/PDALaunchDelegate.java @@ -27,8 +27,6 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; -import org.eclipse.core.variables.IValueVariable; -import org.eclipse.core.variables.VariablesPlugin; import org.eclipse.dd.dsf.concurrent.DataRequestMonitor; import org.eclipse.dd.dsf.concurrent.Query; import org.eclipse.dd.examples.pda.PDAPlugin; @@ -118,32 +116,24 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { private void launchProcess(ILaunch launch, String program, int requestPort, int eventPort) throws CoreException { List commandList = new ArrayList(); - // Find Perl executable - IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); - if (perl == null) { - abort("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", null); - } - String path = perl.getValue(); - if (path == null) { - abort("Perl executable location unspecified. Check value of ${dsfPerlExecutable}.", null); - } - File exe = new File(path); + // Get Java VM path + String javaVMHome = System.getProperty("java.home"); + String javaVMExec = javaVMHome + File.separatorChar + "bin" + File.separatorChar + "java"; + File exe = new File(javaVMExec); if (!exe.exists()) { - abort(MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), null); + abort(MessageFormat.format("Specified java VM executable {0} does not exist.", new Object[]{javaVMExec}), null); } - commandList.add(path); - - // Add PDA VM - File vm = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl")); - if (vm == null) { - abort("Missing PDA VM", null); - } - commandList.add(vm.getAbsolutePath()); + commandList.add(javaVMExec); + + commandList.add("-cp"); + commandList.add(File.pathSeparator + PDAPlugin.getFileInPlugin(new Path("bin"))); + + commandList.add("org.eclipse.dd.examples.pdavm.PDAVirtualMachine"); // Add PDA program IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(program)); if (!file.exists()) { - abort(MessageFormat.format("Perl program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null); + abort(MessageFormat.format("PDA program {0} does not exist.", new Object[] {file.getFullPath().toString()}), null); } commandList.add(file.getLocation().toOSString()); @@ -158,7 +148,7 @@ public class PDALaunchDelegate extends LaunchConfigurationDelegate { Process process = DebugPlugin.exec(commandLine, null); // Create a debug platform process object and add it to the launch. - DebugPlugin.newProcess(launch, process, path); + DebugPlugin.newProcess(launch, process, javaVMHome); } /** diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java index f51fd7d0986..88dc69f1878 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test2.java @@ -57,15 +57,15 @@ public class Test2 extends CommandControlTestsBase { expectEvent("resumed client"); expectEvent("suspended breakpoint 12"); sendCommand("clear 19"); - sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|n|m#" + fProgram + "|12|sub2" ); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|m|n#" + fProgram + "|12|sub2" ); sendCommand("stepreturn"); expectEvent("resumed client"); expectEvent("suspended step"); - sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|n|m#" + fProgram + "|13|sub2" ); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|18|sub1|m|n#" + fProgram + "|13|sub2" ); sendCommand("stepreturn"); expectEvent("resumed client"); expectEvent("suspended step"); - sendCommand("stack", fProgram + "|6|main#" + fProgram + "|22|sub1|n|m" ); + sendCommand("stack", fProgram + "|6|main#" + fProgram + "|22|sub1|m|n" ); sendCommand("set 6"); sendCommand("stepreturn"); expectEvent("resumed client"); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java index 11650200afd..27543a9dc10 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/service/command/Test6.java @@ -41,7 +41,7 @@ public class Test6 extends CommandControlTestsBase { sendCommand("resume"); expectEvent("resumed client"); expectEvent("suspended watch read inner::a"); - sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|25|inner|c|a"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|25|inner|a|c"); sendCommand("watch inner::a 0"); sendCommand("resume"); expectEvent("resumed client"); @@ -64,13 +64,13 @@ public class Test6 extends CommandControlTestsBase { sendCommand("step"); expectEvent("resumed step"); expectEvent("suspended step"); - sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|c|a"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|a|c"); sendCommand("data", "4|4|"); sendCommand("eval call%20other"); expectEvent("resumed client"); expectEvent("evalresult 15"); expectEvent("suspended eval"); - sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|c|a"); + sendCommand("stack", fProgram + "|10|main|a|b#" + fProgram + "|26|inner|a|c"); sendCommand("data", "4|4|"); sendCommand("resume"); expectEvent("resumed client"); diff --git a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java index d859e26cb63..dfc4f3295d7 100644 --- a/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java +++ b/plugins/org.eclipse.dd.examples.pda/src/org/eclipse/dd/tests/pda/util/Launching.java @@ -20,9 +20,9 @@ import java.util.List; import junit.framework.Assert; import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; -import org.eclipse.core.variables.IValueVariable; -import org.eclipse.core.variables.VariablesPlugin; +import org.eclipse.core.runtime.Status; import org.eclipse.dd.examples.pda.PDAPlugin; import org.eclipse.debug.core.DebugPlugin; @@ -30,19 +30,6 @@ import org.eclipse.debug.core.DebugPlugin; * */ public class Launching { - public static String getPerlPath() { - // Perl executable - IValueVariable perl = VariablesPlugin.getDefault().getStringVariableManager().getValueVariable(PDAPlugin.VARIALBE_PERL_EXECUTABLE); - Assert.assertNotNull("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", perl); - - String path = perl.getValue(); - Assert.assertNotNull("Perl executable location undefined. Check value of ${dsfPerlExecutable}.", path); - Assert.assertTrue( - MessageFormat.format("Specified Perl executable {0} does not exist. Check value of $dsfPerlExecutable.", new Object[]{path}), - new File(path).exists()); - - return path; - } public static Process launchPDA(String pdaProgram, int requestPort, int eventPort) throws CoreException { Assert.assertTrue("Invalid request port", requestPort > 0); @@ -50,11 +37,21 @@ public class Launching { List commandList = new ArrayList(); - commandList.add(getPerlPath()); - - File pdaVM = PDAPlugin.getFileInPlugin(new Path("pdavm/pda.pl")); - Assert.assertNotNull("File " + pdaVM + " not found in plugin.", pdaVM); - commandList.add(pdaVM.getAbsolutePath()); + // Get Java VM path + String javaVMHome = System.getProperty("java.home"); + String javaVMExec = javaVMHome + File.separatorChar + "bin" + File.separatorChar + "java"; + File exe = new File(javaVMExec); + if (!exe.exists()) { + throw new CoreException(new Status( + IStatus.ERROR, PDAPlugin.PLUGIN_ID, 0, + MessageFormat.format("Specified java VM executable {0} does not exist.", new Object[]{javaVMExec}), null)); + } + commandList.add(javaVMExec); + + commandList.add("-cp"); + commandList.add(File.pathSeparator + PDAPlugin.getFileInPlugin(new Path("bin"))); + + commandList.add("org.eclipse.dd.examples.pdavm.PDAVirtualMachine"); commandList.add(pdaProgram);