Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple threaded server crashes on Windows XP/7 and native Perl #13123

Closed
p5pRT opened this issue Jul 24, 2013 · 13 comments
Closed

Simple threaded server crashes on Windows XP/7 and native Perl #13123

p5pRT opened this issue Jul 24, 2013 · 13 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 24, 2013

Migrated from rt.perl.org#119003 (status was 'resolved')

Searchable as RT119003$

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2013

From dexter@cpan.org

Created by dexter@cpan.org

The server is​:

#!/usr/bin/perl

use strict;

use threads;

use IO​::Socket;
use Socket qw(IPPROTO_TCP TCP_NODELAY);

sub process_connection {
  my ($sock) = @​_;

  $sock->setsockopt(IPPROTO_TCP, TCP_NODELAY, 1)
  or die "setsockopt(TCP_NODELAY) failed​:$!";

  while (my $line = <$sock>) {
  $line =~ s/\015?\012$//;
  if ($line =~ /^$/) {
  print $sock "HTTP/1.0 200 OK\015\012Content-Type​:
text/plain\015\012\015\012Hello, world!\015\012";
  last;
  };
  };
  close $sock;
}

my $server = IO​::Socket​::INET->new( LocalPort => 5000, Type =>
SOCK_STREAM, Reuse => 1, Listen => SOMAXCONN ) or die ("bind​: $!\n");

warn $server;

sub worker {
  my ($n, $server) = @​_;
  while(my $client = $server->accept) {
  process_connection($client);
  }
}

for my $n (1..20) {
  my $thr = threads->create(\&worker, $n, $server);
}

foreach my $thr (threads->list) {
  $thr->join;
}

The client is​:

ab -c 1 -n 1000 http​://localhost​:5000/

The test fail on Windows XP/7 (MSWin32). It handles a few requests and
throws error​:

Thread 4 terminated abnormally​: setsockopt(TCP_NODELAY) failed​:An operation was
attempted on something that is not a socket. at server-pre-threads.pl line 13.

The test passed on Windows 2003/8 (MSWin32) or ealier (cygwin).

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.18.0:

Configured by strawberry-perl at Sat May 18 17:47:09 2013.

Summary of my perl5 (revision 5 version 18 subversion 0) configuration:

  Platform:
    osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread-64int
    uname='Win32 strawberry-perl 5.18.0.1 #1 Sat May 18 17:46:00 2013 i386'
    config_args='undef'
    hint=recommended, useposix=true, d_sigaction=undef
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='gcc', ccflags =' -s -O2 -DWIN32  -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO
-fno-strict-aliasing -mms-bitfields',
    optimize='-s -O2',
    cppflags='-DWIN32'
    ccversion='', gccversion='4.6.3', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='long long', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE"
-L"C:\strawberry\c\lib"'
    libpth=C:\strawberry\c\lib C:\strawberry\c\i686-w64-mingw32\lib
    libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32
-lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool
-lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid
-lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
    libc=, so=dll, useshrplib=true, libperl=libperl518.a
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
    cccdlflags=' ', lddlflags='-mdll -s
-L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"'

Locally applied patches:



@INC for perl 5.18.0:
    C:/strawberry/perl/site/lib/MSWin32-x86-multi-thread-64int
    C:/strawberry/perl/site/lib
    C:/strawberry/perl/vendor/lib
    C:/strawberry/perl/lib
    .


Environment for perl 5.18.0:
    HOME (unset)
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin
    PERL_BADLANG (unset)
    SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2013

From @jdhedden

IO​::Socket is not threads-safe. See the 'BUGS AND LIMITATIONS' of the
'threads' POD. This ticket should be closed out as 'rejected'.

On Wed, Jul 24, 2013 at 6​:31 AM, Piotr Roszatycki <perlbug-followup@​perl.org

wrote​:

# New Ticket Created by Piotr Roszatycki
# Please include the string​: [perl #119003]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=119003 >

This is a bug report for perl from dexter@​cpan.org,
generated with the help of perlbug 1.39 running under perl 5.18.0.

-----------------------------------------------------------------
[Please describe your issue here]

The server is​:

#!/usr/bin/perl

use strict;

use threads;

use IO​::Socket;
use Socket qw(IPPROTO_TCP TCP_NODELAY);

sub process_connection {
my ($sock) = @​_;

$sock\->setsockopt\(IPPROTO\_TCP\, TCP\_NODELAY\, 1\)
    or die "setsockopt\(TCP\_NODELAY\) failed&#8203;:$\!";

while \(my $line = \<$sock>\) \{
    $line =~ s/\\015?\\012$//;
    if \($line =~ /^$/\) \{
        print $sock "HTTP/1\.0 200 OK\\015\\012Content\-Type&#8203;:

text/plain\015\012\015\012Hello, world!\015\012";
last;
};
};
close $sock;
}

my $server = IO​::Socket​::INET->new( LocalPort => 5000, Type =>
SOCK_STREAM, Reuse => 1, Listen => SOMAXCONN ) or die ("bind​: $!\n");

warn $server;

sub worker {
my ($n, $server) = @​_;
while(my $client = $server->accept) {
process_connection($client);
}
}

for my $n (1..20) {
my $thr = threads->create(\&worker, $n, $server);
}

foreach my $thr (threads->list) {
$thr->join;
}

The client is​:

ab -c 1 -n 1000 http​://localhost​:5000/

The test fail on Windows XP/7 (MSWin32). It handles a few requests and
throws error​:

Thread 4 terminated abnormally​: setsockopt(TCP_NODELAY) failed​:An
operation was
attempted on something that is not a socket. at server-pre-threads.plline 13.

The test passed on Windows 2003/8 (MSWin32) or ealier (cygwin).

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags​:
category=core
severity=medium
---
Site configuration information for perl 5.18.0​:

Configured by strawberry-perl at Sat May 18 17​:47​:09 2013.

Summary of my perl5 (revision 5 version 18 subversion 0) configuration​:

Platform​:
osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread-64int
uname='Win32 strawberry-perl 5.18.0.1 #1 Sat May 18 17​:46​:00 2013 i386'
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
use64bitint=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='gcc', ccflags =' -s -O2 -DWIN32 -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO
-fno-strict-aliasing -mms-bitfields',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='4.6.3', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long long', ivsize=8, nvtype='double', nvsize=8,
Off_t='long long', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='g++', ldflags ='-s -L"C​:\strawberry\perl\lib\CORE"
-L"C​:\strawberry\c\lib"'
libpth=C​:\strawberry\c\lib C​:\strawberry\c\i686-w64-mingw32\lib
libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32
-lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool
-lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid
-lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
libc=, so=dll, useshrplib=true, libperl=libperl518.a
gnulibc_version=''
Dynamic Linking​:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s
-L"C​:\strawberry\perl\lib\CORE" -L"C​:\strawberry\c\lib"'

Locally applied patches​:

---
@​INC for perl 5.18.0​:
C​:/strawberry/perl/site/lib/MSWin32-x86-multi-thread-64int
C​:/strawberry/perl/site/lib
C​:/strawberry/perl/vendor/lib
C​:/strawberry/perl/lib
.

---
Environment for perl 5.18.0​:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)

PATH=C​:\WINDOWS\system32;C​:\WINDOWS;C​:\WINDOWS\System32\Wbem;C​:\strawberry\c\bin;C​:\strawberry\perl\site\bin;C​:\strawberry\perl\bin
PERL_BADLANG (unset)
SHELL (unset)

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2013

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jul 24, 2013

From @nwc10

On Wed, Jul 24, 2013 at 12​:56​:58PM -0400, Jerry D. Hedden wrote​:

IO​::Socket is not threads-safe. See the 'BUGS AND LIMITATIONS' of the
'threads' POD. This ticket should be closed out as 'rejected'.

Neither the section in threads.pm nor IO​::Socket itself say that it is not
thread safe. So

1) How is anyone supposed to know this?
2) Why isn't IO​::Socket thread safe?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2013

From @jdhedden

On Wed, Jul 24, 2013 at 12​:56​:58PM -0400, Jerry D. Hedden wrote​:

IO​::Socket is not threads-safe. See the 'BUGS AND
LIMITATIONS' of the 'threads' POD. This ticket should be
closed out as 'rejected'.

On Wed, Jul 24, 2013 at 3​:30 PM, Nicholas Clark <nick@​ccl4.org> wrote​:

Neither the section in threads.pm nor IO​::Socket itself
say that it is not thread safe. So

1) How is anyone supposed to know this?

A tough question. There's a section on thread-safety in
perlthrtut. Unless a module says it's thread-safe, it
should not be assumed that is is. Many times modules that
use XS code have not been coded to be thread-safe.

2) Why isn't IO​::Socket thread safe?

It seems I am mistaken in this. I was too hasty in my
assessment, and failed to see the OP's comment that this
code used to work on previous Perl versions.

What is needed is more information. Modifying the example
code as follows​:

  sub process_connection {
  my ($sock) = @​_;
  print(ref($sock), "\n"); # ADDED

would provide insight into the error stating that $sock is
not a socket. (Sorry, but I don't have 5.18 at my disposal
to to this.)

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2013

From dexter@cpan.org

2013/7/25 Jerry D. Hedden <jdhedden@​gmail.com>​:

A tough question. There's a section on thread-safety in
perlthrtut. Unless a module says it's thread-safe, it
should not be assumed that is is. Many times modules that
use XS code have not been coded to be thread-safe.

It is not about module. It is about Perl itself without modules. The
same script rewritten without IO​::Socket. The same result with native
Perl on Windows XP. Cygwin version works without problem.

#!/usr/bin/perl

use strict;
use threads;
require Socket;

sub process_connection {
  my ($sock) = @​_;

  setsockopt $sock, Socket​::IPPROTO_TCP(), Socket​::TCP_NODELAY(), 1
or die "setsockopt​: $!";

  while (my $line = <$sock>) {
  $line =~ s/\015?\012$//;
  if ($line =~ /^$/) {
  print $sock "HTTP/1.0 200 OK\015\012Content-Type​:
text/plain\015\012\015\012Hello, world!\015\012";
  last;
  };
  };
  close $sock;
}

socket my $server, Socket​::AF_INET(), Socket​::SOCK_STREAM(), 0 or die
"socket​: $!";
setsockopt $server, Socket​::SOL_SOCKET(), Socket​::SO_REUSEADDR(),
pack("l", 1) or die "setsockopt​: $!";
bind $server, Socket​::pack_sockaddr_in(5000, "\x00\x00\x00\x00") or
die "bind​: $!";
listen $server, Socket​::SOMAXCONN() or die "listen​: $!";

warn $server;

sub worker {
  my ($n, $server) = @​_;
  while(accept my $client, $server) {
  process_connection($client);
  }
}

for my $n (1..20) {
  my $thr = threads->create(\&worker, $n, $server);
}

--
.''`. Piotr Roszatycki
: :' : mailto​:Piotr.Roszatycki@​gmail.com
`. `' mailto​:dexter@​debian.org
  `-

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2013

From @jdhedden

Piotr,

If you run the script with this line added​:

sub process_connection {
  my ($sock) = @​_;
  print(ref($sock), "\n"); # ADDED

What is the output from this print statement?

On Thu, Jul 25, 2013 at 6​:08 AM, Piotr Roszatycki <dexter@​cpan.org> wrote​:

2013/7/25 Jerry D. Hedden <jdhedden@​gmail.com>​:

A tough question. There's a section on thread-safety in
perlthrtut. Unless a module says it's thread-safe, it
should not be assumed that is is. Many times modules that
use XS code have not been coded to be thread-safe.

It is not about module. It is about Perl itself without modules. The
same script rewritten without IO​::Socket. The same result with native
Perl on Windows XP. Cygwin version works without problem.

#!/usr/bin/perl

use strict;
use threads;
require Socket;

sub process_connection {
my ($sock) = @​_;

setsockopt $sock\, Socket&#8203;::IPPROTO\_TCP\(\)\, Socket&#8203;::TCP\_NODELAY\(\)\, 1

or die "setsockopt​: $!";

while \(my $line = \<$sock>\) \{
    $line =~ s/\\015?\\012$//;
    if \($line =~ /^$/\) \{
        print $sock "HTTP/1\.0 200 OK\\015\\012Content\-Type&#8203;:

text/plain\015\012\015\012Hello, world!\015\012";
last;
};
};
close $sock;
}

socket my $server, Socket​::AF_INET(), Socket​::SOCK_STREAM(), 0 or die
"socket​: $!";
setsockopt $server, Socket​::SOL_SOCKET(), Socket​::SO_REUSEADDR(),
pack("l", 1) or die "setsockopt​: $!";
bind $server, Socket​::pack_sockaddr_in(5000, "\x00\x00\x00\x00") or
die "bind​: $!";
listen $server, Socket​::SOMAXCONN() or die "listen​: $!";

warn $server;

sub worker {
my ($n, $server) = @​_;
while(accept my $client, $server) {
process_connection($client);
}
}

for my $n (1..20) {
my $thr = threads->create(\&worker, $n, $server);
}

--
.''`. Piotr Roszatycki
: :' : mailto​:Piotr.Roszatycki@​gmail.com
`. `' mailto​:dexter@​debian.org
`-

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2013

From dexter@cpan.org

2013/7/25 Jerry D. Hedden <jdhedden@​gmail.com>​:

sub process_connection {
my ($sock) = @​_;
print(ref($sock), "\n"); # ADDED

What is the output from this print statement?

GLOB(0x3f7d8c) at H​:\src\server-pre-threads.pl line 31.
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
GLOB
Thread 3 terminated abnormally​: setsockopt​: An operation was attempted on someth
ing that is not a socket. at H​:\src\server-pre-threads.pl line 14.

@p5pRT
Copy link
Author

p5pRT commented Aug 8, 2013

From @wchristian

On Windows 7, with ActivePerl 5.12.4 the following works for me​:

https://gist.github.com/wchristian/a90bcd5a854fa0ea76ee

@p5pRT
Copy link
Author

p5pRT commented Sep 30, 2013

From @jdhedden

I strongly suspect this is the same as bug # 119897 which has been resolved.
https://rt-archive.perl.org/perl5/Public/Bug/Display.html?id=119897
If someone can verify this, then this bug can be resolved, too.

On Thu, Aug 8, 2013 at 9​:20 AM, Christian Walde via RT
<perlbug-followup@​perl.org> wrote​:

On Windows 7, with ActivePerl 5.12.4 the following works for me​:

https://gist.github.com/wchristian/a90bcd5a854fa0ea76ee

---
via perlbug​: queue​: perl5 status​: open
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=119003

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 2013

From dexter@cpan.org

On Pon 30 Wrz 2013, 08​:36​:13, jdhedden@​gmail.com wrote​:

I strongly suspect this is the same as bug # 119897 which has been resolved.

I tested this script with Perl 5.19.6 compiled for Windows XP and it worked correctly.

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 2013

From @jkeenan

On Wed Dec 11 09​:24​:11 2013, dexter@​cpan.org wrote​:

On Pon 30 Wrz 2013, 08​:36​:13, jdhedden@​gmail.com wrote​:

I strongly suspect this is the same as bug # 119897 which has been
resolved.

I tested this script with Perl 5.19.6 compiled for Windows XP and it
worked correctly.

Marking this ticket resolved.

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Dec 11, 2013

@jkeenan - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant