Change of behavior of the "system" function?

Hello all.

I am not an experienced ruby programmer, but some time ago I developed an ARM Simulator Core for the m0 architecture that has been working for two years now both on Linux and Windows, and we use at our university for teaching computer architecture.

You can find more information following
http://lorca.act.uji.es/project/qtarmsim

Suddenly the simulator stopped working on my Windows 8.1 computer. Debugging the code I have arrived to the crashing code, that is

assemble = Proc.new { |entrada|
   nf = entrada[0].split('.')[0]
   fline = $path + nf
   cline = '"' + $compiler + '"' + ' ' + $args + ' -Wa,-alcd' + ' -o ' + fline + '.o'
   eline = '2>' + fline + '.err'
   lline = '>' + fline + '.lst'
   if system(cline + ' ' + fline + '.s ' + ' ' + lline + ' ' + eline)
     blocks = read_ELF(fline + '.o')
     procesador = Core.new(ThumbII_Defs::ARCH, blocks[0])
     procesador.memory.add_block(blocks[1])
     procesador.memory.symbolTable = blocks[2]
     $symbol_table = blocks[2]
     dirPC = $symbol_table['main']
     dirPC = ORIG_CODE if dirPC.nil?
     procesador.update({usr_regs: [ThumbII_Defs::PC, dirPC, ThumbII_Defs::SP, END_DATA - 128]})
     $server.proc = procesador
     $source = gen_source(fline + '.lst')
     p $source
     res = "SUCCESS\r\n"
   else
     res = "ERROR\r\n"
     File.foreach(fline + '.err') do |line|
       res = res + line[0..-2] + "\r\n"
     end
     res = res + "EOF\r\n"
   end
   File.delete(fline + '.err')
   File.delete(fline + '.lst')
   res
}

where the simulator calls the compiler to generate the obj file to obtain the machine code to simulate, the .lst to generate the assembly listing and the .err to report errors if any. Please forgive my bad ruby but this was my first (and only to date) ruby application.

As I have told, everything worked ok and works on many platforms but now, on my Windows 8.1 system -and I have to say it previously worked- it doesn't, and I observe:

The line sent to the shell by the system call is
"C:/Program Files (x86)/arduino-1.5.4/hardware/tools/g++_arm_none_eabi/bin/arm-none-eabi-gcc.exe" -mcpu=cortex-m1 -mthumb -c -Wa,-alcd -o program.o program.s >program.lst 2>program.err

and the shell reports the errors
arm-none-eabi-gcc.exe: >program.lst: Invalid argument
arm-none-eabi-gcc.exe: 2>program.err: Invalid argument

Which means that the redirections > and 2> are considered as parameters to the compiler and not correctly interpreted by the shell.

This happens with versions 1.93 and 2.2 of ruby. And what puzzles me the most is that it worked as the simulator has been being used for more than two years now!

Thank you very much for your attention.
Germán Fabregat.

Hi
i'm relatively new to Ruby, but:
start a shell with your line as args!
Berg

···

Am 14.07.2016 11:07 schrieb "German Fabregat" <fabregat@uji.es>:

Hello all.

I am not an experienced ruby programmer, but some time ago I developed an
ARM Simulator Core for the m0 architecture that has been working for two
years now both on Linux and Windows, and we use at our university for
teaching computer architecture.

You can find more information following
http://lorca.act.uji.es/project/qtarmsim

Suddenly the simulator stopped working on my Windows 8.1 computer.
Debugging the code I have arrived to the crashing code, that is

assemble = Proc.new { |entrada|
  nf = entrada[0].split('.')[0]
  fline = $path + nf
  cline = '"' + $compiler + '"' + ' ' + $args + ' -Wa,-alcd' + ' -o ' +
fline + '.o'
  eline = '2>' + fline + '.err'
  lline = '>' + fline + '.lst'
  if system(cline + ' ' + fline + '.s ' + ' ' + lline + ' ' + eline)
    blocks = read_ELF(fline + '.o')
    procesador = Core.new(ThumbII_Defs::ARCH, blocks[0])
    procesador.memory.add_block(blocks[1])
    procesador.memory.symbolTable = blocks[2]
    $symbol_table = blocks[2]
    dirPC = $symbol_table['main']
    dirPC = ORIG_CODE if dirPC.nil?
    procesador.update({usr_regs: [ThumbII_Defs::PC, dirPC,
ThumbII_Defs::SP, END_DATA - 128]})
    $server.proc = procesador
    $source = gen_source(fline + '.lst')
    p $source
    res = "SUCCESS\r\n"
  else
    res = "ERROR\r\n"
    File.foreach(fline + '.err') do |line|
      res = res + line[0..-2] + "\r\n"
    end
    res = res + "EOF\r\n"
  end
  File.delete(fline + '.err')
  File.delete(fline + '.lst')
  res
}

where the simulator calls the compiler to generate the obj file to obtain
the machine code to simulate, the .lst to generate the assembly listing and
the .err to report errors if any. Please forgive my bad ruby but this was
my first (and only to date) ruby application.

As I have told, everything worked ok and works on many platforms but now,
on my Windows 8.1 system -and I have to say it previously worked- it
doesn't, and I observe:

The line sent to the shell by the system call is
"C:/Program Files
(x86)/arduino-1.5.4/hardware/tools/g++_arm_none_eabi/bin/arm-none-eabi-gcc.exe"
-mcpu=cortex-m1 -mthumb -c -Wa,-alcd -o program.o program.s >program.lst
2>program.err

and the shell reports the errors
arm-none-eabi-gcc.exe: >program.lst: Invalid argument
arm-none-eabi-gcc.exe: 2>program.err: Invalid argument

Which means that the redirections > and 2> are considered as parameters to
the compiler and not correctly interpreted by the shell.

This happens with versions 1.93 and 2.2 of ruby. And what puzzles me the
most is that it worked as the simulator has been being used for more than
two years now!

Thank you very much for your attention.
Germán Fabregat.

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

Hi German,

assemble = Proc.new { |entrada|
   [snip]
   if system(cline + ' ' + fline + '.s ' + ' ' + lline + ' ' + eline)
  [snip]
}

Please only post those parts of the code that are actually relevant, in
this case, the call to the #system method. It would be even better if
you created a minimal self-contained example that one can run to
reproduce the problem, without having to dig into your main application.

As I have told, everything worked ok and works on many platforms but
now, on my Windows 8.1 system -and I have to say it previously
worked- it doesn't

This sounds as if a Windows update changed behaviour of whatever
"shell" #system invokes internally (most likely cmd.exe). I don't use
Ruby on Windows (and I bet most of the people on this list do neither),
but you might want to revert some updates and see if you can pinpoint
it.

Which means that the redirections > and 2> are considered as
parameters to the compiler and not correctly interpreted by the shell.

While I have no direct explanation as to why this stopped working, you
could skip the shell entirely by using the extended version of #system.
The #system method supports the same parameters as the #spawn method; if
you call it with each commandline argument as a separate parameter, Ruby
will skip the shell and instead directly run the command. As a bonus,
you can specify the redirection in Ruby code. Please refer to the
extensive documentation of the #spawn method[1]. As an example, to run
a command and redirect its output to a file, you can use something like
this:

  system("/bin/echo", "test",
         :out => "/tmp/out.log",
         :err => "/tmp/err.log")

Obviously, you'll have to adapt this to your use case, but doing it
this way skips both the shell and the redirect within the shell,
allowing you to directly do things in Ruby.

Greetings
Marvin

[1]: Module: Process (Ruby 2.3.1)

···

Am Thu, 14 Jul 2016 11:06:38 +0200 schrieb German Fabregat <fabregat@uji.es>:

--
Blog: http://www.guelkerdev.de
PGP/GPG ID: F1D8799FBCC8BC4F

Thank you very much, Marvin.

You example has solved my problem, although I still don't know its cause.

I have followed your example

   system("/bin/echo", "test",
          :out => "/tmp/out.log",
          :err => "/tmp/err.log")

passing as first argument my command line with all of its arguments,
without redirecting the outputs. Then I have added the hashes you add to your example and everything works perfect! And I guess it is much more robust than my original call to system.

Regards,
Germán Fabregat.