poppopjmp / shedskin

Automatically exported from code.google.com/p/shedskin
0 stars 0 forks source link

os.urandom returns wrong type, segfaults #114

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. shedskin osurandomtest.py
2. make
3. ./osurandomtest.exe

Or, for debug:
1. shedskin osurandomtest.py
2. make osurandomtest_debug 
3. gdb osurandomtestdebug

What is the expected output? What do you see instead?

$ gdb osurandomtest_debug
GNU gdb 6.8.0.20080328-cvs (cygwin-special)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) run
Starting program: /home/nagle/rpython-libs/lib/work/osurandomtest_debug
[New thread 2664.0xb44]
Error: dll starting at 0x776f0000 not found.
Error: dll starting at 0x76e80000 not found.
Error: dll starting at 0x776f0000 not found.
Error: dll starting at 0x775f0000 not found.
[New thread 2664.0xe40]

Program received signal SIGSEGV, Segmentation fault.
__shedskin__::ord (s=0x0) at 
/home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.hpp:1721
1721    template<class T> inline __ss_int len(T x) { return x->__len__(); }
(gdb) bt
#0  __shedskin__::ord (s=0x0) at 
/home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.hpp:17
#1  0x0040de2f in __osurandomtest__::_RandomNameSequence () at 
osurandomtest.cpp:25
#2  0x0040de9b in __osurandomtest__::test () at osurandomtest.cpp:37
#3  0x0040d458 in __shedskin__::__start (initfunc=0x40def0 
<__osurandomtest__::__init()>)
    at /home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.cpp:2082
#4  0x0040dbd6 in main () at osurandomtest.cpp:64
(gdb)

What version of the product are you using? On what operating system?

Shed Skin 0.6, Cygwin, Windows 7

Please provide any additional information below.

"os.urandom(n)" is supposed to return n random bytes. In Python 2.6, it returns 
an ASCII "str" (since Python 2.6 doesn't distinguish between strings and arrays 
of bytes), and in Python 2.6, "ord" of each character in the string will 
extract a value in the range 0..255.

Shed Skin accept the same source code, but something goes wrong and the code 
segfaults at the "ord" call.  Unclear why.  The generated C++ code
looks reasonable.  

Original issue reported on code.google.com by na...@animats.com on 15 Nov 2010 at 3:29

Attachments:

GoogleCodeExporter commented 8 years ago
Here's a slightly different version, with some extra print statements.
Debugger output:

$ gdb osurandomtest_debug
GNU gdb 6.8.0.20080328-cvs (cygwin-special)
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-cygwin"...
(gdb) run
Starting program: /home/nagle/rpython-libs/lib/work/osurandomtest_debug
[New thread 3556.0xb44]
Error: dll starting at 0x776f0000 not found.
Error: dll starting at 0x76e80000 not found.
Error: dll starting at 0x776f0000 not found.
Error: dll starting at 0x775f0000 not found.
[New thread 3556.0xb0c]
'\xc8\xaehS<\x1e'
Random byte: None

Program received signal SIGSEGV, Segmentation fault.
__shedskin__::ord (s=0x0) at 
/home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.hpp:1721
1721    template<class T> inline __ss_int len(T x) { return x->__len__(); }
(gdb) bt
#0  __shedskin__::ord (s=0x0) at 
/home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.hpp:1721
#1  0x0040de83 in __osurandomtest__::_RandomNameSequence () at 
osurandomtest.cpp:28
#2  0x0040df5b in __osurandomtest__::test () at osurandomtest.cpp:42
#3  0x0040d458 in __shedskin__::__start (initfunc=0x40dfb0 
<__osurandomtest__::__init()>)
    at /home/nagle/shedskin/shedskin-0.6/shedskin/lib/builtin.cpp:2082
#4  0x0040dbd6 in main () at osurandomtest.cpp:71
(gdb)

Note the lines

'\xc8\xaehS<\x1e'
Random byte: None

6 random bytes were generated, and "repr" printed them as a string.  But "ord" 
returned 0, and then led to a crash. 

What puzzles me is that if I replace the call to os.urandom with something like
bt = "ABCDEF"
the code does not crash.

The debugger says that at the point of the crash, "n" is a null pointer.  
That's presumably why "ord" got a segfault. But n should be a pointer to a 
one-character string at that point, obtained from subscripting "bt".  I can 
dump "bt":

(gdb) print *bt
$3 = {<__shedskin__::pyseq<__shedskin__::str*>> = 
{<__shedskin__::pyiter<__shedskin__::str*>> = {<__shedskin__::pyobj> = {<gc> = 
{<N
o data fields>}, _vptr$pyobj = 0x433ec8, __class__ = 0xbf0fa8}, <No data 
fields>},
    units = {<std::_Vector_base<__shedskin__::str*, gc_allocator<__shedskin__::str*> >> = {
        _M_impl = {<gc_allocator<__shedskin__::str*>> = {<No data fields>}, _M_start = 0x0, _M_finish = 0x0,
          _M_end_of_storage = 0x0}}, <No data fields>}}, unit = {static npos = 4294967295,
    _M_dataplus = {<gc_allocator<char>> = {<No data fields>}, _M_p = 0xbf2774 "?hS<\036"}}, hash = -1}
(gdb)

And "units" of bt:

(gdb) print *bt->units
Structure has no component named operator*.
(gdb) print (*bt)->units
$4 = {<std::_Vector_base<__shedskin__::str*, gc_allocator<__shedskin__::str*> 
>> = {
    _M_impl = {<gc_allocator<__shedskin__::str*>> = {<No data fields>}, _M_start = 0x0, _M_finish = 0x0,
      _M_end_of_storage = 0x0}}, <No data fields>}

which is a null string and shouldn't be.

Also notice that in the stack backtrace, the stack is off; it shows control in 
"len", which is wrong.  Running without the debugger, I get

$ ./osurandomtest_debug.exe
'8\x00\x16\xd1\xc8\x03'
Random byte: '8'
Random byte as integer: 56
Random byte: '\x00'
Random byte as integer: 0
Random byte: '\x16'
Random byte as integer: 22
Random byte: None
      2 [main] osurandomtest_debug 3052 exception::handle: Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)

so something clobbbered the stack.

Original comment by na...@animats.com on 15 Nov 2010 at 4:00

Attachments:

GoogleCodeExporter commented 8 years ago
thanks! :D

test minimized to:

for n in '"\xd8\xc3A~s':
    print repr(n)

expect a fix in GIT shortly..

Original comment by mark.duf...@gmail.com on 15 Nov 2010 at 2:45

GoogleCodeExporter commented 8 years ago
ah, the __char_cache (we talked about this by mail, a 1-length string cache) 
was apparently not always indexed with a positive index, because of forgetting 
to cast the index first.. leading to a string pointer to an arbitrary memory 
location. fixed in GIT, thanks again for all the issues!! :)

Original comment by mark.duf...@gmail.com on 15 Nov 2010 at 5:04

GoogleCodeExporter commented 8 years ago
Oh, characters being treated as signed.  That's why iterating over "ABCDEF" 
didn't cause a crash.

(I understanding indexing into a table of boxed items. Some systems that box 
integers use that for small ints.)

Original comment by na...@animats.com on 15 Nov 2010 at 6:43