Issue588452
Created on 2002-07-30 09:13 by mwh, last changed 2022-04-10 16:05 by admin. This issue is now closed.
| Files |
| File name |
Uploaded |
Description |
Edit |
|
marshal.c.diff
|
theller,
2002-07-30 11:03
|
Patch for Python/marshal.c |
|
| Messages (6) |
|
msg11747 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-07-30 09:13 |
I have no idea how long this bug has existed for. I
could well be a long time. I noticed it while trying
to kill off SET_LINENO.
To reproduce, build a debug python, cd to Tools/freeze/
and run
$ /path/to/python -O freeze.py hello.py
I get a wodge ot modulefinder (I presume) output, and then:
freezing BaseHTTPServer ...
freezing FixTk ...
freezing SocketServer ...
freezing StringIO ...
freezing Tkconstants ...
freezing Tkinter ...
python: ../Python/marshal.c:66: w_more: Assertion
`(int)(char)(c) == (c)' failed.
Aborted (core dumped)
This is on x86; on my PPC laptop where I discovered
this, it gets quite a bit further before dying. So
maybe some endianness fun.
The assert that fails is in a Py_SAFEDOWNCAST macro.
I have *no* idea where to start with this one;
assigning to Thomas because I have a vague recollection
he knows something about how freeze works <evil cackle>
-- feel free to reassign!
|
|
msg11748 - (view) |
Author: Thomas Heller (theller) *  |
Date: 2002-07-30 10:09 |
Logged In: YES
user_id=11105
Fails for me too (Win2k, python debug build). But it is a
marshal issue!
Here's a script to reproduce it when running with a debug
build:
import marshal; marshal.dumps([128] * 1000)
(anything between 128 and 255 will trigger the error, and the
list must be large enough.
The debugger shows that w_long is called with x = 128, and
than w_more() is called with c = 128, and the
Py_SAFEDOWNCAST macro fails, maybe because char is
signed on this platform.
|
|
msg11749 - (view) |
Author: Thomas Heller (theller) *  |
Date: 2002-07-30 11:03 |
Logged In: YES
user_id=11105
As I can see, the proper fix is to replace
static void
w_long(long x, WFILE *p)
{
w_byte((int)( x & 0xff), p);
w_byte((int)((x>> 8) & 0xff), p);
w_byte((int)((x>>16) & 0xff), p);
w_byte((int)((x>>24) & 0xff), p);
}
with
static void
w_long(long x, WFILE *p)
{
w_byte((char)( x & 0xff), p);
w_byte((char)((x>> 8) & 0xff), p);
w_byte((char)((x>>16) & 0xff), p);
w_byte((char)((x>>24) & 0xff), p);
}
and similar for the w_short() function.
Even safer would be to use the Py_SAFE_DOWNCAST
macro also in the w_byte macro.
Attached a patch for marshal.c.
|
|
msg11750 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-07-30 11:15 |
Logged In: YES
user_id=6656
That fixes both my initial problem and your test case. Nice
work!
Check it in and add a test case?
It would be nice to have w_byte as an inline function with
sensible declaration...
|
|
msg11751 - (view) |
Author: Thomas Heller (theller) *  |
Date: 2002-07-30 11:42 |
Logged In: YES
user_id=11105
Check in and added test case:
committed * Up-To-Date 1.3 Lib/test/test_marshal.py
committed * Up-To-Date 1.73 Python/marshal.c
|
|
msg11752 - (view) |
Author: Guido van Rossum (gvanrossum) *  |
Date: 2002-07-30 18:40 |
Logged In: YES
user_id=6380
Nice work guys!
(Now I wonder where Py_SAFE_DOWNCAST comes from. :-)
|
|
History
|
|---|
| Date |
User |
Action |
Args |
| 2022-04-10 16:05:32 | admin | set | github: 36948 |
| 2002-07-30 09:13:48 | mwh | create | |