Bugs: Browse | Submit New | Admin

[#23485] IOError when writing relatively large buffers to STDOUT

Date:
2009-01-07 19:43
Priority:
3
Submitted By:
Daniele Alessandri (nrk)
Assigned To:
Tomas Matousek (tmat)
Category:
None
State:
Open
Summary:
IOError when writing relatively large buffers to STDOUT

Detailed description
IronRuby throws an IOError when a relatively large quantity of data is passed to methods like Kernel#puts or Kernel#print,
but only if $stdout == STDOUT (that is, the current standard output is the console IO). See below:


IronRuby SVN r182:
  >>> puts "0" * 100_000
  mscorlib:0:in `WinIOError': Not enough storage is available to process this command. (IOError)
          from mscorlib:0:in `Write'
          from C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:682:in `write'
          from C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:648:in `puts'
          from C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\KernelOps.cs:604:in `puts'
          from :0


MRI 1.8.6 (output has been cut down here for obvious reasons)
  irb(main):002:0> puts "0" * 100_000
  0000000000000000000000000000 [...] 00000
  => nil


IronRuby works correctly when the current standard output is replaced with any other IO instance:


IronRuby SVN r182:
  >>> $stdout = File.open('tmp.txt', 'w')
  => #<File:tmp.txt>
  >>> puts "0" * 100_000
  => nil


The resulting file will contain 100,000 characters as expected. 

I digged a little bit into this issue with a step-by-step debug and it seems it all comes down to a limit (which seems
to vary depending on the resource being used by the system) on how much data can be written at once on
a System.IO.__ConsoleStream before incurring a Win32 native error ERROR_NOT_ENOUGH_MEMORY. In fact, the implementation
of the Write method of IronRuby.Builtins.ConsoleStream tries to write the entire buffer all at once but this leads to
the above mentioned native error.

Here is, for reference, the full stack trace generated by the System.IO.IOException:

   in System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   in System.IO.__ConsoleStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   in IronRuby.Builtins.ConsoleStream.Write(Byte[] buffer, Int32 offset, Int32 count)
in C:\Sviluppo\ironruby\SVN\trunk\src\ironruby\Builtins\ConsoleStream.cs:riga 88
   in IronRuby.Builtins.RubyIO.Write(Byte[] buffer, Int32 index, Int32 count) in
C:\Sviluppo\ironruby\SVN\trunk\src\ironruby\Builtins\IO.cs:riga 401
   in IronRuby.Builtins.RubyIO.Write(MutableString value) in C:\Sviluppo\ironruby\SVN\trunk\src\ironruby\Builtins\IO.cs:riga
386
   in IronRuby.Builtins.RubyIOOps.Write(RubyIO self, MutableString val)
in C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:riga 682
   in _stub_$508(Closure , CallSite , RubyContext , Object , Object )
   in System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
in C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting.Core\Actions\UpdateDelegates.Generated.cs:riga 503
   in IronRuby.Builtins.RubyIOOps.Puts(RubyContext context, Object self, MutableString str)
in C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:riga 648
   in IronRuby.Builtins.RubyIOOps.Puts(UnaryOpStorage tosStorage, RubyContext context, Object self, Object val)
in C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:riga 657
   in IronRuby.Builtins.RubyIOOps.Puts(UnaryOpStorage tosStorage, RubyContext context, Object self, Object[] vals) in
C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\IoOps.cs:riga 663
   in IronRuby.Builtins.KernelOps.PrintInspect(UnaryOpStorage tosStorage, RubyContext context, Object self, Object[]
args) in C:\Sviluppo\ironruby\SVN\trunk\src\IronRuby.Libraries\Builtins\KernelOps.cs:riga 524
   in _stub_$506(Closure , CallSite , RubyScope , Object , Object )
   in System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
in C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting.Core\Actions\UpdateDelegates.Generated.cs:riga 503
   in #top-level-method#$1(Closure , Scope , LanguageContext )
   in Microsoft.Scripting.ScriptCode.InvokeTarget(LambdaExpression code, Scope scope)
in C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs:riga 90
   in Microsoft.Scripting.ScriptCode.Run(Scope scope) in
C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting\Runtime\ScriptCode.cs:riga 82
   in IronRuby.Runtime.RubyContext.ExecuteProgram(SourceUnit program) in
C:\Sviluppo\ironruby\SVN\trunk\src\ironruby\Runtime\RubyContext.cs:riga 1763
   in Microsoft.Scripting.Hosting.ScriptSource.ExecuteProgram() in
C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting\Hosting\ScriptSource.cs:riga 185
   in Microsoft.Scripting.Hosting.Shell.CommandLine.RunFile(ScriptSource source)
in C:\Sviluppo\ironruby\SVN\trunk\src\Microsoft.Scripting\Hosting\Shell\CommandLine.cs:riga 180

Add A Comment: Notepad

Please login


Followup

No Followups Have Been Posted

Attached Files:

Name Description Download
No Files Currently Attached

Changes:

Field Old Value Date By
assigned_tonone2009-01-07 20:36tmat