Hello, 

Through ACRA, I have received a small number of reports from an alpha build 
of software that show that an exception is occurring during a specific call 
to Canvas.restore(). The exception is java.lang.IllegalStateException: 
Underflow in restore.

I am well aware that this exception shall occur if one too many restore() 
calls are made than save() calls. However, from very careful code 
inspection, I am absolutely certain that all calls to canvas.save() and 
canvas.restore() are balanced. That is, all calls to canvas.save() are most 
certainly balanced at a later stage by a call to canvas.restore(). I can 
also confirm that there are no conditionals, exceptions or early returns 
from methods that could result in a missing canvas.save() leading to the 
stack underflow.

Furthermore, this issue seems to be a rare edge-case that is resulting in 
the exception happening only a handful of times within graphics code that 
renders many times every second.

The sort of structure of the code in which this is happening is:


protected void onDraw(Canvas canvas) {
    ...
    someMethod(canvas);
    ...
}

void someMethod(Canvas canvas)
{
    ....
    canvas.save();
    ....
    someOtherMethod(Canvas canvas);
    ....
    canvas.restore();   
    ....
}

void someOtherMethod(Canvas canvas)
{

    ....
    canvas.save();
    ....
    for ( ... ) {
    
        ....
        canvas.save();
        ...
        canvas.restore();
        ...
    } 
    ....
    canvas.restore();   // *** exception here ***    
    ....
}


There are places where save() / restore() is used within a loop, but again 
the calls are balanced. 

The reports are from devices running 4.3 and 4.4.2.

I have attempted to Google this issue and the only interesting QA I could 
find (on Stackoverflow) was from a person who clearly had unbalanced save() 
/ restore() calls in his code; that is categorically not the issue in my 
case. 

This is occurring within the call stack of a custom View subclass' 
onDraw(Canvas canvas) method, all happening on the UI thread. There are no 
other threads I have touching that Canvas object.

I could potentially check the stack with a call to getSaveCount() before 
invoking the specific restore() that has been responsible for the 
exceptions, but that would really be just sticking an Elastoplast over the 
problem. I'd rather understand what on earth the edge case is that's 
causing the underflow, but it is baffling me. 

Are there any known issues? Could it be possible for any kind of system 
configuration change to affect this Canvas while the UI thread is within 
the context of a View's onDraw() call? Are there any known limitations on 
the Canvas stack size? Could there be any OS graphics calls that are known 
to misuse the canvas stack?


Thanks,


Trev



-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to