Bug #7721

test_too_long_path2(TestProcess) fails on mingw32

Added by Heesob Park about 1 year ago. Updated about 1 year ago.

[ruby-core:51557]
Status:Closed
Priority:Normal
Assignee:Nobuyoshi Nakada
Category:-
Target version:-
ruby -v:38934 Backport:

Description

[ 6319/11317] TestProcess#testtoolong_path2Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.

C:\work\snapshot-mg32>exit
= 8.03 s
33) Failure:
testtoolongpath2(TestProcess) [C:/work/snapshot-mg32/test/ruby/testprocess.rb:1393]:
.
[Errno::ENOENT, Errno::E2BIG] expected but nothing was raised.

This failure is also mentioned at https://bugs.ruby-lang.org/issues/7710#note-3

0001-error.c-defer-error-message.patch Magnifier (6.7 KB) Nobuyoshi Nakada, 01/25/2013 11:42 AM

Associated revisions

Revision 38904
Added by Nobuyoshi Nakada about 1 year ago

win32.c: acptowstr results check

  • win32/win32.c (rbw32spawn, rbw32aspawnflags): check the results of acpto_wstr() which can return NULL. [Bug #7721]

Revision 38909
Added by Nobuyoshi Nakada about 1 year ago

win32.c: missing initialization

  • win32/win32.c (rbw32spawn, rbw32aspawn_flags): fix missing initialization. pointed out by phasis68 (Heesob Park) at . [Bug #7721]

Revision 38934
Added by Nobuyoshi Nakada about 1 year ago

test_process.rb: reduce command string size

  • test/ruby/testprocess.rb (testspawntoolongpath), (testaspawntoolong_path): reduce command string size until intended exception occurs. [Bug #7721]

History

#1 Updated by Heesob Park about 1 year ago

After some inspections, I found this failure occurs not on a very long path but on a sufficiently long path with many preloaded test sets.

On such a condition, acptowstr or mbstrtowstr function returns NULL with the failure of malloc.

Here is a workaround patch:
diff --git a/win32.c b/win32.c.new
index 3b82766..4822f63 100644
--- a/win32.c
+++ b/win32.c.new
@@ -1126,7 +1126,7 @@ CreateChild(const WCHAR *cmd, const WCHAR *prog, SECURITY_ATTRIBUTES *psa,

 dwCreationFlags |= NORMAL_PRIORITY_CLASS;
  • if (lstrlenW(cmd) > 32767) {
  • if (cmd==NULL || lstrlenW(cmd) > 32767) { child->pid = 0; /* release the slot */ errno = E2BIG; return NULL;

#2 Updated by Jon Forums about 1 year ago

Nice Process.spawn spelunking.

The patch also works for me on Win7 32bit with mingw-w64 4.7.2 on ruby 2.0.0dev (2013-01-22 trunk 38896) [i386-mingw32]

#3 Updated by Nobuyoshi Nakada about 1 year ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r38904.
Heesob, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


win32.c: acptowstr results check

  • win32/win32.c (rbw32spawn, rbw32aspawnflags): check the results of acpto_wstr() which can return NULL. [Bug #7721]

#4 Updated by Nobuyoshi Nakada about 1 year ago

  • Tracker changed from Bug to Backport
  • Project changed from ruby-trunk to Backport93
  • Status changed from Closed to Assigned
  • Assignee set to Usaku NAKAMURA

#5 Updated by Heesob Park about 1 year ago

This bug is not solved with changeset r38904.

There are some warnings.

compiling win32/win32.c
win32/win32.c: In function 'rbw32aspawn_flags':
win32/win32.c:1296:14: warning: 'ret' may be used uninitialized in this function

win32/win32.c: In function 'rbw32spawn':
win32/win32.c:1187:14: warning: 'ret' may be used uninitialized in this function

win32/win32.c: In function 'rbw32aspawn_flags.clone.8':
win32/win32.c:1296:14: warning: 'ret' may be used uninitialized in this function

And the test still fails.

19) Failure:
testtoolongpath2(TestProcess) [C:/work/snapshot-mg32/test/ruby/testprocess.rb:1393]:
.
[Errno::ENOENT, Errno::E2BIG] expected but nothing was raised.

Here is a patch:
diff --git a/win32.c b/win32.c.new
index 8b577ea..984e03b 100644
--- a/win32.c
+++ b/win32.c.new
@@ -1184,7 +1184,7 @@ rbw32spawn(int mode, const char *cmd, const char *prog)
const char *shell = NULL;
WCHAR *wcmd = NULL, *wshell = NULL;
int e = 0;
- rbpidt ret;
+ rbpidt ret = -1;
VALUE v = 0;
VALUE v2 = 0;

@@ -1293,7 +1293,7 @@ rbw32aspawnflags(int mode, const char *prog, char *const *argv, DWORD flags)
char *cmd, fbuf[MAXPATHLEN];
WCHAR *wcmd = NULL, *wprog = NULL;
int e = 0;
- rb
pidt ret;
+ rb
pid_t ret = -1;
VALUE v = 0;

 if (check_spawn_mode(mode)) return -1;

#6 Updated by Luis Lavena about 1 year ago

  • Assignee changed from Usaku NAKAMURA to Nobuyoshi Nakada
  • % Done changed from 100 to 50

I can confirm, test still fails:

http://ci.rubyinstaller.org/job/ruby-trunk-x86-test-all/703/console

testtoolongpath2(TestProcess) [C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/testprocess.rb:1393]:
.
[Errno::ENOENT, Errno::E2BIG] exception expected, not
Class:
Message: <"failed to allocate memory">
---Backtrace---
C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/test_process.rb:1393:in initialize'
C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/test_process.rb:1393:in
spawn'

C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/testprocess.rb:1393:in `block in testtoolongpath2'

#7 Updated by Luis Lavena about 1 year ago

  • Tracker changed from Backport to Bug
  • Project changed from Backport93 to ruby-trunk

#8 Updated by Heesob Park about 1 year ago

The NoMemoryError is raised from rbsyserrnewstr call in makeerrnoexcstr function with too long path string.

Here is a patch:
diff --git a/error.c b/error.c.new
index 481c117..c26feff 100644
--- a/error.c
+++ b/error.c.new
@@ -1859,6 +1859,9 @@ makeerrnoexc_str(VALUE mesg)
{
int n = errno;

+#ifdef E2BIG
+ if (n == E2BIG) mesg = Qnil;
+#endif

errno = 0;
if (!mesg) mesg = Qnil;
if (n == 0) {

#9 Updated by Nobuyoshi Nakada about 1 year ago

  • Status changed from Assigned to Closed
  • % Done changed from 50 to 100

This issue was solved with changeset r38934.
Heesob, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


test_process.rb: reduce command string size

  • test/ruby/testprocess.rb (testspawntoolongpath), (testaspawntoolong_path): reduce command string size until intended exception occurs. [Bug #7721]

#10 Updated by Nobuyoshi Nakada about 1 year ago

NoMemoryError could occur at many places, almostly everywhere creating
a new object, adding a new instance variable, growing up a container
object, etc. It's just rare in normal cases.

r30682 reduced the sizes from 100MB to 10MB because NoMemoryError is
not intended, but testtoolongpath2 is still consuming double of
test
toolongpath.

I fix these tests instead for the time being.

Another strategy is, similar to NameError::message, keeping the given
parameters untouched and defer generating the message until to_s is
called. But it's complex considering Marshal.

Also available in: Atom PDF