Bug #7721

test_too_long_path2(TestProcess) fails on mingw32

Added by Heesob Park over 2 years ago. Updated over 2 years ago.

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

Description

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

C:\work\snapshot-mg32>exit
= 8.03 s
33) Failure:
test_too_long_path2(TestProcess) [C:/work/snapshot-mg32/test/ruby/test_process.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 over 2 years ago

win32.c: acp_to_wstr results check

  • win32/win32.c (rb_w32_spawn, rb_w32_aspawn_flags): check the results of acp_to_wstr() which can return NULL. [Bug #7721]

Revision 38904
Added by Nobuyoshi Nakada over 2 years ago

win32.c: acp_to_wstr results check

  • win32/win32.c (rb_w32_spawn, rb_w32_aspawn_flags): check the results of acp_to_wstr() which can return NULL. [Bug #7721]

Revision 38909
Added by Nobuyoshi Nakada over 2 years ago

win32.c: missing initialization

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

Revision 38909
Added by Nobuyoshi Nakada over 2 years ago

win32.c: missing initialization

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

Revision 38934
Added by Nobuyoshi Nakada over 2 years ago

test_process.rb: reduce command string size

  • test/ruby/test_process.rb (test_spawn_too_long_path), (test_aspawn_too_long_path): reduce command string size until intended exception occurs. [Bug #7721]

Revision 38934
Added by Nobuyoshi Nakada over 2 years ago

test_process.rb: reduce command string size

  • test/ruby/test_process.rb (test_spawn_too_long_path), (test_aspawn_too_long_path): reduce command string size until intended exception occurs. [Bug #7721]

History

#1 Updated by Heesob Park over 2 years 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, acp_to_wstr or mbstr_to_wstr 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 over 2 years 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 over 2 years ago

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

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: acp_to_wstr results check

  • win32/win32.c (rb_w32_spawn, rb_w32_aspawn_flags): check the results of acp_to_wstr() which can return NULL. [Bug #7721]

#4 Updated by Nobuyoshi Nakada over 2 years ago

  • Project changed from Ruby trunk to Backport193
  • Tracker changed from Bug to Backport
  • Status changed from Closed to Assigned
  • Assignee set to Usaku NAKAMURA

#5 Updated by Heesob Park over 2 years ago

This bug is not solved with changeset r38904.

There are some warnings.

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

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

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

And the test still fails.

19) Failure:
test_too_long_path2(TestProcess) [C:/work/snapshot-mg32/test/ruby/test_process.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 @@ rb_w32_spawn(int mode, const char *cmd, const char *prog)
const char *shell = NULL;
WCHAR *wcmd = NULL, *wshell = NULL;
int e = 0;
- rb_pid_t ret;
+ rb_pid_t ret = -1;
VALUE v = 0;
VALUE v2 = 0;

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

 if (check_spawn_mode(mode)) return -1;

#6 Updated by Luis Lavena over 2 years 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

test_too_long_path2(TestProcess) [C:/Users/Worker/Jenkins/workspace/ruby-trunk-x86-build/test/ruby/test_process.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/test_process.rb:1393:in `block in test_too_long_path2'

#7 Updated by Luis Lavena over 2 years ago

  • Tracker changed from Backport to Bug
  • Project changed from Backport193 to Ruby trunk

#8 Updated by Heesob Park over 2 years ago

The NoMemoryError is raised from rb_syserr_new_str call in make_errno_exc_str 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 @@ make_errno_exc_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 over 2 years 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/test_process.rb (test_spawn_too_long_path), (test_aspawn_too_long_path): reduce command string size until intended exception occurs. [Bug #7721]

#10 Updated by Nobuyoshi Nakada over 2 years 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 test_too_long_path2 is still consuming double of
test_too_long_path.

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