bugText Extractor TXR - Bugs: bug #28016, Issue in cobj construction order...

 
 

bug #28016: Issue in cobj construction order leads to gc fault.

Submitted by:  Kaz Kylheku <kkylheku>
Submitted on:  Sat 14 Nov 2009 10:19:48 AM UTC  
 
Category: NoneSeverity: 4 - Important
Item Group: CorrectnessStatus: Fixed
Privacy: PublicAssigned to: Kaz Kylheku <kkylheku>
Originator Name: Open/Closed: Closed
Component Version: 020Operating System: None
Fixed Release: 021Planned Release: 021
Architecture: AllABI: All

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Sun 15 Nov 2009 08:46:56 PM UTC, comment #1:

Fixed.

Kaz Kylheku <kkylheku>
Project AdministratorIn charge of this item.
Sat 14 Nov 2009 10:19:48 AM UTC, original submission:

A gc-related bug occurs in make_stdio_stream or any similar function which follows the same pattern:

obj_t make_stdio_stream(FILE f, obj_t descr, obj_t input, obj_t *output)
{
struct stdio_handle h = (struct stdio_handle ) chk_malloc(sizeof *h);
h->f = f;
h->descr = descr;
return cobj((void *) h, stream_t, &stdio_ops.cobj_ops);
}

In this function, a struct (an object outside of the managed object system) is allocated, and an object reference is placed into it: h->descr = descr. At this point, the compiler may decide that h->descr is the only place which has a reference to that object. This is a problem if the object was constructed right inside the call to the function, as happens in txr.c:

yyin_stream = make_stdio_stream(in, string_utf8(*argv), t, nil);

The garbage collector knows nothing about structure h, and so if the cobj function invokes gc, h->descr is reclaimed.

Only when h is connected into the allocated cobj does h->descr become reachable, thanks to the mark function in stdio_ops.cobj_ops. But the gc call may take place while the cobj is being allocated, before the h structure is hooked into it.

This issue reproduced when I compiled with an older gcc on i686 with -O2 and -p for profiling.

The following code rearrangement makes it go away:

obj_t make_stdio_stream(FILE f, obj_t descr, obj_t input, obj_t *output)
{
struct stdio_handle h = (struct stdio_handle ) chk_malloc(sizeof *h);
obj_t stream = cobj((void ) h, stream_t, &stdio_ops.cobj_ops);
h->f = f;
h->descr = descr;
return stream;
}

Now the cobj with handle h is prepared first, before descr is stashed into the handle structure. So during the cobj call, the descr ref is maintained in a register or on the stack: places visible to gc.

Kaz Kylheku <kkylheku>
Project AdministratorIn charge of this item.

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by kkylheku (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 5 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Sun 15 Nov 2009 08:46:56 PM UTCkkylhekuFixed ReleaseNone=>021
      Open/ClosedOpen=>Closed
      StatusConfirmed=>Fixed
    Sat 14 Nov 2009 10:22:30 AM UTCkkylhekuSummarygc bug due to cobj construction order=>Issue in cobj construction order leads to gc fault.
    Sat 14 Nov 2009 10:20:55 AM UTCkkylhekuPlanned ReleaseNone=>021

    Back to the top


    Powered by Savane 3.1-cleanup1