Project

General

Profile

Actions

Bug #7721

closed

test_too_long_path2(TestProcess) fails on mingw32

Added by phasis68 (Heesob Park) over 11 years ago. Updated about 11 years ago.

Status:
Closed
Target version:
-
ruby -v:
38934
Backport:
[ruby-core:51557]

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]:
[ruby-core:34833].
[Errno::ENOENT, Errno::E2BIG] expected but nothing was raised.

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


Files

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

Updated by phasis68 (Heesob Park) over 11 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;

Updated by jonforums (Jon Forums) over 11 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]

Actions #3

Updated by nobu (Nobuyoshi Nakada) over 11 years 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: 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. [ruby-core:51557] [Bug #7721]
Actions #4

Updated by nobu (Nobuyoshi Nakada) over 11 years ago

  • Tracker changed from Bug to Backport
  • Project changed from Ruby master to Backport193
  • Status changed from Closed to Assigned
  • Assignee set to usa (Usaku NAKAMURA)

Updated by phasis68 (Heesob Park) over 11 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.

  1. Failure:
    test_too_long_path2(TestProcess) [C:/work/snapshot-mg32/test/ruby/test_process.rb:1393]:
    [ruby-core:34833].
    [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;

Updated by luislavena (Luis Lavena) over 11 years ago

  • Assignee changed from usa (Usaku NAKAMURA) to nobu (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]:
[ruby-core:34833].
[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'

Actions #7

Updated by luislavena (Luis Lavena) over 11 years ago

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

Updated by phasis68 (Heesob Park) about 11 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) {
Actions #9

Updated by nobu (Nobuyoshi Nakada) about 11 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. [ruby-core:51592] [Bug #7721]

Updated by nobu (Nobuyoshi Nakada) about 11 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.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0