Tuomo Valkonen <[EMAIL PROTECTED]> writes:

> On Wed, Feb 23, 2005 at 07:27:48PM +0100, Matthieu Moy wrote:
>> Open an xterm, call
>> 
>>   detach.topmost_transient_to_float(_sub, nil, false)
>> 
>> on it, and close it. (save your work before ;-)
>
> Nothing unexpected happens. Could you add those debug messages I
> described previously (more spcifically, something like
> fprintf(stderr, "%p %s\n", mgr, OBJ_TYPESTR(mgr));) and let me know
> the output just before the crash?

Oh, silly me. I forgot to mention that you have to call

ioncore.get_hook("frame_managed_changed_hook"):add(detach.maybe_leave_layer2)

before closing the last layer 2 item. Sorry...

After investigating a bit, the problem seems to be that
region_detach_manager hook frame_managed_changed_hook, that calls
detach.maybe_leave_layer2.

If you set detach.make_ion_crash = true, this hook closes the layer 2
workspace with rqclose_relocate. I guess this kind of recursive call
is unexpected: rqclose_relocate in the hook will relocate the
clientwin, and the clientwin will have a manager when the hook
returns. Therefore, the assertion fails.

I've instrumented region_detach_manager like this:


void region_detach_manager(WRegion *reg)
{
    WRegion *mgr;

    mgr=REGION_MANAGER(reg);

    fprintf(stderr, "entering region_detach_manager().\n");
    fprintf(stderr, "mgr: %p %s\n", mgr, OBJ_TYPESTR(mgr));
    fprintf(stderr, "reg: %p %s\n", reg, OBJ_TYPESTR(reg));
    fprintf(stderr, "reg-mgr: %p %s\n", REGION_MANAGER(reg),
    OBJ_TYPESTR(REGION_MANAGER(reg)));

    if(mgr==NULL)
        return;

    /* Restore activity state to non-parent manager */
    if(region_may_control_focus(reg)){
        fprintf(stderr, "inside the if().\n");
        WRegion *par=REGION_PARENT_REG(reg);
        if(par!=NULL && mgr!=par && REGION_PARENT_REG(mgr)==par){
            /* REGION_ACTIVE shouldn't be set for windowless regions
             * but make the parent's active_sub point to it
             * nevertheless so that region_may_control_focus can
             * be made to work.
             */
            par->active_sub=mgr;
            /*if(region_xwindow(mgr)!=None){*/
                region_do_set_focus(mgr, FALSE);
            /*}*/
        }
    }

    region_clear_activity(reg, TRUE);

    fprintf(stderr, "after region_clear_activity().\n");
    fprintf(stderr, "mgr: %p %s\n", mgr, OBJ_TYPESTR(mgr));
    fprintf(stderr, "reg: %p %s\n", reg, OBJ_TYPESTR(reg));
    fprintf(stderr, "reg-mgr: %p %s\n", REGION_MANAGER(reg), 
OBJ_TYPESTR(REGION_MANAGER(reg)));

    region_managed_remove(mgr, reg);

    fprintf(stderr, "just before the assertion.\n");
    fprintf(stderr, "mgr: %p %s\n", mgr, OBJ_TYPESTR(mgr));
    fprintf(stderr, "reg: %p %s\n", reg, OBJ_TYPESTR(reg));
    fprintf(stderr, "reg-mgr: %p %s\n", REGION_MANAGER(reg),
    OBJ_TYPESTR(REGION_MANAGER(reg)));
    assert(REGION_MANAGER(reg)==NULL);
}

And I get the following trace. (# comments added by me)

entering region_detach_manager().
mgr: 0x80f7ac0 WFloatFrame
reg: 0x8143b90 WClientWin
reg-mgr: 0x80f7ac0 WFloatFrame
after region_clear_activity().
mgr: 0x80f7ac0 WFloatFrame
reg: 0x8143b90 WClientWin
reg-mgr: 0x80f7ac0 WFloatFrame
# This one is called from the hook.
entering region_detach_manager().
mgr: (nil) (null)
reg: 0x8143b90 WClientWin
reg-mgr: (nil) (null)
# We're comming back to the first call
just before the assertion.
mgr: 0x80f7ac0 WFloatFrame
reg: 0x8143b90 WClientWin
reg-mgr: 0x809dbf8 WScreen
ion3: region.c:476: region_detach_manager: Assertion 
`(((WRegion*)(reg))->manager)==((void *)0)' failed.

I don't know what's the best solution to this problem, probably this
should end up with a lua error, but clearly, assertion failure is not
good.

Hope this helps...

-- 
Matthieu

Reply via email to