This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: $DEBUG_PYTHON -O freeze.py broken
Type: Stage:
Components: None Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: theller Nosy List: gvanrossum, mwh, theller
Priority: normal Keywords:

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) (Python committer) 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) * (Python committer) 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) * (Python committer) 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) (Python committer) 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) * (Python committer) 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) * (Python committer) 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:32adminsetgithub: 36948
2002-07-30 09:13:48mwhcreate