This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Remote testing cross-gcc


mike stump wrote:
> > From: Dimi Shahbaz <dshahbaz@ixiacom.com>
> 
> > I have been wrestling with dejagnu and the gcc testsuites for more
> > than a few days now.  I am trying to test a cross compiler tool
> > chain.  I cannot determine how to instruct dejagnu (or the gcc
> > testsuites) to compile the tests on the local machine (i686) and run
> > them (e.g., transfer them, telnet into the machine, and execute the
> > test) on a remote machine (ppc).
> 
> > I am not entirely sure this is even possible, because I can find no
> > information in the gcc manual.
> 
> Yes, it is possible, people do it all the time.
> 
> > Has anyone been able to do something like this?
> 
> Sure.
> 
> You have to do up a board file, put all the right stuff in it...
> It uses telnet by default, so no problem there...
> 
> Anyway, the dejagnu list might be a better place to talk about it.
> 
> Check out all the existing configuration files (*.exp in lib and
> config and base-boards) for hints.

mail.gnu.org is down today :-( or I'd ask on the dejagnu list.

I'm trying to pick up where Dimi left off (he finished his internship
and has moved on).  I, too, find dejagnu extremely poorly documented
and frustrating for the newcomer.  Here's how I'm trying to
come up the learning curve:

First, I installed the gcc3.0.1 source rpm from redhat 7.2 and
built it.  Then I did
  cd /usr/src/redhat/BUILD/gcc-3.0.1-20010905/obj-i386-redhat-linux/gcc
  make check
and verified that it happily started doing local dejagnu tests.

Then I beat the crap out of the Makefile in that directory
until it revealed the command it used to run the tests.
Turns out to be just "runtest --tool gcc", which was not at
all obvious from the highly convoluted and obscure Makefile.

So now I can do
  runtest --tool gcc
and it does a bunch of tests on my local machine.  How the f**k
does one convince it to run remotely via telnet and ftp or rcp?  
Hours of searching yields no answer.  The doc is fragmented and useless.
Thoughts of nuclear weapons dropping on the Dejagnu authors dance
through my head.  The command helpfully says
  Running target unix
  Using /usr/share/dejagnu/baseboards/unix.exp as board description file for target.
  Using /usr/share/dejagnu/config/unix.exp as generic interface file for target.
  Using /usr/src/redhat/BUILD/gcc-3.0.1-20010905/gcc/testsuite/config/default.exp as tool-and-target-specific interface file.
but unfortunately reading through /usr/share/dejagnu/config/unix.exp leaves
me no closer to enlightenment about how one might coax it into
using telnet/rsh/rcp/ftp.  It does contain lines like
       if ![is_remote $dest] {
but there's no clue how one sets $dest; it appears to be a parameter
to the function unix_load, but a full grep of dejagnu finds no
calls to that function.  Arrgh.  ARRRGH.

Can someone give me simple instructions on how to coax gcc's
testsuite into simply running remotely on a unix box of the
same architecture sitting next to the build machine?  Without
telling me to go get a PhD in TCL?

Thanks...
- Dan



> 
> In my case, I do something like:
> 
> t22-163.exp:
> set_board_info vxworks_homedir /folk/myacct/testDir/t22-163
> load_base_board_description "vxpowerpc"
> set_board_info x10 3
> set_board_info "kernel,vxworks" $WIND_BSPBASE/target/config/mv2603/vxWorks
> set_board_info cflags " -mstrict-align -DCPU=PPC603 -DMV2600 "
> 
> and then in vxpowerpc.exp, we can do something like:
> 
> # This is a list of toolchains that are supported on this board.
> set_board_info target_install {m68k-vxworks5.1 m68k-vxworks5.2}
> 
> # Load the generic configuration for this board. This will define any
> # routines needed by the tool to communicate with the board.
> load_generic_config "vxworks";
> 
> # No multilib flags by default.
> process_multilib_options "";
> 
> # The compiler used to build for this board. Note that this has nothing to do
> # with what compiler is tested when testing gcc.
> set_board_info compiler "[find_gcc]";
> 
> # These are probably wrong.
> set_board_info cflags "";
> # vxworks 5.1 needs the executable to be relinkable.
> set_board_info ldflags "-nostdlib -r";
> set_board_info libs "-lgcc";
> 
> # No linker script needed.
> set_board_info ldscript "";
> 
> # GDB needs to use "target vxworks" to talk to the board.
> set_board_info gdb_protocol "vxworks";
> 
> and then in vxworks.exp, something like:
> 
> # Copyright (C) 92, 93, 94, 95, 1996, 1997 Free Software Foundation, Inc.
> 
> # This program is free software; you can redistribute it and/or modify
> # it under the terms of the GNU General Public License as published by
> # the Free Software Foundation; either version 2 of the License, or
> # (at your option) any later version.
> #
> # This program is distributed in the hope that it will be useful,
> # but WITHOUT ANY WARRANTY; without even the implied warranty of
> # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> # GNU General Public License for more details.
> #
> # You should have received a copy of the GNU General Public License
> # along with this program; if not, write to the Free Software
> # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
> 
> # Please email any bugs, comments, and/or additions to this file to:
> # DejaGnu@cygnus.com
> 
> # This file was originally written by Rob Savoye. (rob@cygnus.com)
> # and modified by Bob Manson (manson@cygnus.com)
> 
> #
> # Try to boot the machine into the requested OS.
> #
> proc ${board}_init { dest } {
>     # This is not the right way to determine the required OS...
>     global target_os;
>     set shell_prompt [board_info $dest shell_prompt];
>     set do_reboot 0;
> 
>     set desired_kernel [board_info $dest "kernel,$target_os"];
> 
>     if { $desired_kernel == "" } {
>         vxworks_final_init $dest;
>         # Nothing to see here, nothing to do. Move along.
>         return;
>     }
> 
>     remote_raw_open $dest raw;
>     remote_send $dest "\n";
>     remote_expect $dest 5 {
>         -re "$shell_prompt" {
>             set do_reboot 1;
>         }
>         -re "Press any key to stop auto-boot" {
>             remote_send $dest "\n";
>             exp_continue;
>         }
>         -re "VxWorks Boot" {
>             set boot_mon 0;
>             set boot_mon_prompt "VxWorks Boot";
>         }
>         -re "\[0-9\]\[\r\n\]+ *\[0-9\]\[\r\n\]" {
>             remote_send $dest "\n";
>             exp_continue;
>         }
>         timeout {
>             set do_reboot 1;
>         }
>     }
> 
>     if { $do_reboot } {
>         remote_close $dest;
>         remote_reboot $dest;
>         return;
>     }
>     remote_binary $dest;
>     remote_send $dest "\n\n";
>     remote_expect $dest 3 {
>         timeout {}
>         -re ".+" { exp_continue; }
>     }
>     remote_send $dest "p\n";
>     remote_expect $dest 20 {
>         -re "file name\[ \t\]+: (\[^ \r\n\]+)\[ \r\n\]+" {
>             set curr_file $expect_out(1,string);
>             exp_continue;
>         }
>         -re "$boot_mon_prompt" { }
>     }
>     if { $curr_file != $desired_kernel } {
>         verbose "$curr_file != '$desired_kernel'";
>         # Oh boy.
>         remote_send $dest "c\n";
>         remote_expect $dest 20 {
>             -re "file name\[ \t\]+:.*$" {
>                 remote_send $dest "$desired_kernel\n";
>                 exp_continue;
>             }
>             -re "\[a-z() \t\]+:.*$" {
>                 remote_send $dest "\n";
>                 exp_continue;
>             }
>             -re "$boot_mon_prompt" {}
>         }
>     }
>     remote_send $dest "@\n";
>     remote_expect $dest 30 {
>         -re "(^|\[\r\n\])$shell_prompt" {}
>         -re ".+" {
>             exp_continue;
>         }
>     }
>     vxworks_final_init $dest;
>     remote_close $dest;
> }
> 
> proc vxworks_final_init { dest } {
>     if [board_info $dest exists preload_obj] {
>         if { [target_compile [board_info $dest preload_obj] foo.out object ""] == "" } {
>             vxworks_ld $dest foo.out
>         }
>         remote_file build delete foo.out;
>     }
> }
> #
> # Execute the command PROGRAM on VxWorks.
> #
> 
> proc vxworks_exec { dest program pargs inp outp } {
>     global decimal hex;
> 
>     set shell_id [vxworks_open $dest];
>     if { $shell_id < 0 } {
>         return [list -1 "open failure"];
>     }
> 
>     if { $inp != "" } {
>         set inp [remote_download $dest $inp];
>         set suffix " < $inp";
>     } else {
>         set suffix ""
>     }
> 
>     set shell_prompt [board_info $dest shell_prompt];
>     remote_send $dest "${program} ${pargs}$suffix\n";
>     # FIXME: The value 300 below should probably be a parameter passed in.
>     remote_expect $dest 300 {
>         -re "\\\[VxWorks Boot\\\]:" {
>             remote_send $dest "@\n";
>             sleep 20;
>             exp_continue;
>         }
>         -re "(.*)value = (-*$decimal) = $hex.*$shell_prompt" {
>             set result [list $expect_out(2,string) $expect_out(1,string)];
>         }
>         -re "undefined symbol: .*$shell_prompt" {
>             set result [list 1 "unknown command"];
>         }
>         default {
>             set result [list -1 "unable to execute command"];
>         }
>     }
>     if { $suffix != "" } {
>         remote_file $dest delete $inp;
>     }
>     return $result;
> }
> 
> proc vxworks_download { dest localfile remotefile } {
>     if [board_info $dest exists vxworks_homedir] {
>         set rfile "[board_info $dest vxworks_homedir]/$remotefile";
>         remote_download build $localfile $rfile;
>         return $rfile;
>     }
>     return [remote_raw_download $dest $localfile $remotefile];
> }
> 
> proc vxworks_file { dest op args } {
>     set file [lindex $args 0];
>     if [board_info $dest exists vxworks_homedir] {
>         set dir "[board_info $dest vxworks_homedir]";
>         switch $op {
>             exists {
>                 set file "${dir}/[file tail $file]";
>                 return [file exists $file];
>             }
>             delete {
>                 foreach x $args {
>                     set x "${dir}/[file tail $x]";
>                     if { [file exists $x] && [file isfile $x] } {
>                         exec rm -f $x;
>                     }
>                 }
>                 return;
>             }
>         }
>     }
>     return [eval remote_raw_file \"$dest\" \"$op\" $args];
> }
> 
> proc vxworks_send { dest string } {
>     # Convert LFs to CRs, 'cause that is what VxWorks wants to see.
>     regsub -all "\n" $string "\r" string;
>     verbose "Sending '$string' to $dest" 2
>     return [remote_raw_send $dest "$string"];
> }
> 
> proc vxworks_open { dest args } {
>     if [board_info $dest exists fileid] {
>         return [board_info $dest fileid];
>     }
> 
>     set shell_prompt [board_info $dest shell_prompt]
> 
>     set shell_id [remote_raw_open $dest];
> 
>     if { $shell_id == "" || $shell_id < 0 } {
>         return -1;
>     }
> 
>     if [board_info $dest exists logname] {
>         set logname [board_info $dest logname];
>         if [board_info $dest exists password] {
>             remote_send $dest "iam \"$logname\",\"[board_info $dest passwd]\"\r"
>         } else {
>             remote_send $dest "iam \"$logname\"\r"
>         }
> 
>         remote_expect $dest 30 {
>             "iam*value = 0 = 0x0*$shell_prompt" {
>                 verbose "Set default user." 2
>             }
>             timeout {
>                 # ??? This is really an error.  It's not clear whether `perror'
>                 # or `warning' should be used here.  There are *lots* of other
>                 # cases like this.
>                 perror "Couldn't set default user."
>                 return -1;
>             }
>         }
>     }
> 
>     set dir "";
>     if [board_info $dest exists ftp_directory] {
>         set dir [board_info $dest ftp_directory];
>     }
>     if [board_info $dest exists vxworks_homedir] {
>         set dir [board_info $dest vxworks_homedir];
>     }
>     if { $dir != "" } {
>         set status [remote_exec $dest "cd" "\"$dir\""];
>         if [lindex $status 0] {
>             perror "Error in cd to $dir--[lindex $status 1]";
>             return 1;
>         }
>     }
>     return $shell_id;
> }
> #
> # Load a file into vxworks
> #
> # The result is:
> #  0 - success
> #  1 - failed (eg: link failed so testcase should fail)
> # -1 - unresolved (eg: timeout), may be fixed by rebooting
> #
> proc vxworks_ld { dest prog } {
>     global decimal hex
>     global board_info
> 
>     if { $prog == "" } {
>         return 1;
>     }
> 
>     set shell_id [remote_open $dest];
> 
>     if { $shell_id < 0 } {
>         return -1;
>     }
> 
>     set prog [remote_download $dest $prog];
> 
>     set shell_prompt [board_info $dest shell_prompt];
> 
>     # We always want to exit the program via the code at the end.
>     # If the load fails we want `expect_out' stored in the log and this
>     # saves duplicating that code.
> 
>     for { set x 0 ; } { $x < 3 } {incr x; } {
>         remote_send $dest "\n";
>         remote_expect $dest 30 {
>             -re ".*$shell_prompt $" { set x 20; }
>             -re "\\\[VxWorks Boot\\\]:" {
>                 remote_send $dest "@\n";
>                 sleep 20;
>                 exp_continue;
>             }
>             timeout { return -1; }
>         }
>     }
> 
>     set tries 0
>     set maxtries 3
>     set result -7       ;# -7 is a local value meaning "not done"
> 
>     while { $result == -7 && $tries < $maxtries } {
>         verbose "Loading $prog into vxworks."
>         remote_send $dest "ld < $prog\n";
>         incr tries
>         remote_expect $dest 300 {
>             -re "USER.*command not understood" {
>                 perror "Need to set the user and password."
>                 set result 1
>             }
>             -re "Stale NFS file handle.*$shell_prompt $" {
>                 # Need to retry.
>             }
>             -re "undefined symbol:.*$shell_prompt $" {
>                 # This is an error in the testcase, don't call perror.
>                 warning "Undefined symbol, $prog not loaded."
>                 set result 1
>             }
>             -re "memPartAlloc: block too.*$shell_prompt $" {
>                 perror "Not enough memory to load $prog."
>                 set result -1
>             }
>             -re "can't open input.*$shell_prompt $" {
>                 perror "Can't access $prog."
>                 set result 1
>             }
>             -re "value = (-*${decimal}) = ${hex}.*$shell_prompt $" {
>                 verbose "Loaded $prog into vxworks."
>                 set board_info([board_info $dest name],vx_module) $expect_out(1,string);
>                 set result 0
>             }
>             -re "(.*)$shell_prompt $" {
>                 warning "Load failed: $expect_out(1,string)"
>             }
>             timeout {
>                 warning "Timed out trying load $prog."
>                 set result -1
>             }
>         }
>     }
> 
>     if { $result && [info exists expect_out(buffer)] } {
>         send_log "$expect_out(buffer)"
>     }
> 
>     remote_file $dest delete $prog;
>     return $result
> }
> 
> #
> # Start a thread (process) executing
> #
> # The result is:
> #  0 - success
> #  1 - failed (eg: testcase aborted)
> # -1 - unresolved, may be fixed by rebooting
> #
> proc vxworks_run { dest function pargs inp outp } {
>     global hex decimal;
> 
>     set shell_prompt [board_info $dest shell_prompt];
>     set output "";
> 
>     # There isn't a command to wait for a thread to finish, so we have to keep
>     # polling. Instead, we expect the status wrapper to return an exit
>     # status.
> 
>     set status [remote_exec $dest "sp" "$function $pargs" $inp $outp];
> 
>     set tid [lindex $status 0];
> 
>     # Bad task id, reboot and try again.
>     if { $tid == -1 || $tid == 0 } {
>         return -1;
>     }
> 
>     set result 1;
>     # FIXME: The value 300 below should be a parameter.
>     remote_expect $dest 300 {
>         -re "task ${hex} - aborted.*$shell_prompt $" {
>             # FIXME: It's not clear we'll ever get here.
>             verbose "$function aborted"
>             set result 1
>         }
>         -re "\[\r\n\]syntax error\[\r\n\]" {
>             verbose "weirdness after task started"
>             set result -1;
>         }
>         -re "(.*)\\*\\*\\* EXIT code ($decimal)\[\r\n\]" {
>             set output "$expect_out(1,string)";
>             set exit_code "$expect_out(2,string)";
>             if { ($exit_code + 0) != 0 } {
>                 set result 1;
>             } else {
>                 set result 0;
>             }
>         }
>         -re ".*AbOrT.*$shell_prompt $" {
>             # This requires support from the environment to
>             # redefine abort() to print this.
>             verbose "$function aborted"
>             set result 1
>         }
>         -re ".*Bus Error.*$" {
>             # This is here to try to cope with apparently flaky h/w.
>             # This is potentially an error in the testcase,
>             # don't call perror.
>             warning "Bus Error."
>             # Delete the task (it's still around).
>             remote_exec $dest "td" "$tid";
>             set result 1
>         }
>         timeout {
>             # Infinite loop? probably.
>             remote_exec $dest "td" "$tid";
>             set result 1;
>         }
>     }
> 
>     return [list $result $output];
> }
> 
> #
> # Unload the last executable that we loaded, so we can free up its memory.
> #
> proc vxworks_unld { dest } {
>     global board_info;
> 
>     if [board_info $dest exists vx_module] {
>         remote_exec $dest "unld" "[board_info $dest vx_module]";
>         unset board_info([board_info $dest name],vx_module);
>     }
> }
> 
> #
> # We loop around rebooting the box until either the load and run
> # "work" or we give up.
> #
> proc vxworks_load {dest prog args} {
>     set result "";
>     set output "";
> 
>     if { [llength $args] > 0 } {
>         set pargs "[lindex $args 0]";
>     } else {
>         set pargs ""
>     }
> 
>     if { [llength $args] > 1 } {
>         set inp "[lindex $args 1]";
>     } else {
>         set inp ""
>     }
> 
>     if { [llength $args] > 2 } {
>         set outp "[lindex $args 2]";
>     } else {
>         set outp ""
>     }
> 
>     for { set x 0; } { $x < 3 } { incr x } {
>         set status [vxworks_ld $dest $prog];
>         if { $status >= 0 } {
>             if { $status > 0 } {
>                 set result "fail";
>             } else {
>                 set out [vxworks_run $dest __wrap_main $pargs $inp $outp];
>                 set status [lindex $out 0];
>                 set output [lindex $out 1];
>                 if { $status != 0 } {
>                     if { $status > 0 } {
>                         set result "fail";
>                     }
>                 } else {
>                     set result "pass";
>                 }
>             }
>         }
>         if { $result != "" } {
>             vxworks_unld $dest;
>             return [list $result $output];
>         }
>         remote_reboot $dest;
>     }
>     return [list "fail" ""];
> }
> 
> set_board_info protocol "vxworks"
> # -lm under vxworks isn't needed.
> set_board_info mathlib ""
> set_board_info shell_prompt "->"
> set_board_info needs_status_wrapper 1
> # FTP doesn't work in passive mode to this board.
> set_board_info ftp_no_passive 1
> # Wait 5 seconds after powercycling.
> set_board_info reboot_delay 5
> 
> # We don't have sys/unistd.h.
> set_board_info wrap_compile_flags "-DNO_UNISTD_H"
> 
> set_board_info gdb_prompt "\[(\]vxgdb\[)\]"
> 
> set_board_info is_vxworks 1;
> set_board_info gdb,nosignals 1;
> 
> and then, off we go...  (parts of that are from fairly old config
> stuff, we actually do it a bit different now, but you get the idea).
> We ask to test t22-163, which happens to be a name of a board we can
> telnet into.  The remote_raw_open uses telnet to open up a telnet
> connection.  We use netport (in later configs) to set an arbitrary
> terminal server and an arbitrary port on that server to connect to.
> We transfer files around via _download, all sorts of fun.
> 
> Anyway, run with -v -v -v -v, and watch what it does.  If you want,
> run the debugger.
> 
> I don't have an easy answer for you.
> 
> ------
> Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
> Want to unsubscribe? Send a note to crossgcc-unsubscribe@sources.redhat.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]