[sane-devel] xsane infinite loop lockup - seems to boil down to compiler optimisation difference

David Campbell david at pastornet.net.au
Wed Aug 8 10:30:55 UTC 2007


Hi Oliver,

Yes, that does correct the issue.  Thanks!

Having fixed that, the hp5590 scanner driver works pretty well, although 
there are a couple things I mention below.  If you wouldn't mind taking 
a look over this for me, it would be much appreciated.

[1]
[dcampbel at Vigor12 ~]$ scanimage -L
device `hp5590:libusb:005:008' is a HP 5590 Workgroup scanner
[hp5590] Assertion 'ptr->opts != NULL' failed at hp5590.c:360

Notice the assertion failure.

This problem arises because the implementation is such that if the 
driver has never scanned, ptr->opts is never actually set and if null 
causes sane_exit to get an assertion failure, as above.

I offer a candidate patch to fix the above issue in hp5590.c - see 
http://www.aaa.net.au/campbell/patchfile.txt

[2]
The only other issue with the hp5590 driver I've found is with duplex 
scanning, and I intend to do some work on it to fix it up.  When 
duplex-scanning, the scanner returns the first side of the page top to 
bottom scanned, and the other side of the page bottom to top scanned, so 
with the current hp5590 driver, you end up with very tall double-height 
pages with the top half the right way around and the bottom half upside 
down - it scans both sides as one really tall page.

A question with regards to fixing this - does the sane api insist on 
returning data in top to bottom format, or to correct this issue would I 
need to make the scanner driver buffer the whole bottom-to-top scanned 
page while it is being scanned and then invert the data to return to 
xsane?  It would be nice if a bottom to top scan could be handled by xsane.

-- Dave

Oliver Rauch wrote:
> Hello David,
>
> I think this would be a suitable solution:
>
>
> replace
>  if (val != new_val)
> by
>  if (abs(val - new_val) > 1)
>
> please could you verify if this solves the problem even with -O2
> compiler option!
>
> Best regards
> Oliver
>
> Am Mittwoch, den 08.08.2007, 19:27 +1000 schrieb David Campbell:
>   
>> Hi,
>>
>> OK - thanks for your comment!
>>
>> Here's what I am seeing from the debug entry you request:
>>
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> [xsane] val = 39019942, new_val = 39019943
>> etc forever....
>>
>> A bit of output from gdb, and note that it is taking the SANE_TYPE_FIXED 
>> branch of the switch statement in the code, so the value of val comes 
>> from the SANE_FIX macro.
>>
>> (gdb) p adj_data->value
>> $1 = 59.539707946777341
>> (gdb) p d
>> $2 = 595.39707946777344
>> (gdb) p val
>> $3 = 39019942
>> (gdb) p new_val
>> $5 = 39019943
>>
>> You can simulate exactly what is going on here with this bit of tiny C 
>> source code below, which hard-codes the binary representation of 59.5397 
>> from above, and you can see that the resulting behaviour depends on 
>> whether you compile with optimization or not, and you get 390199423 or 
>> 39019942 respectively.  Also, uncommenting the printf comments below 
>> changes the compiler's decision about whether to use registers or not to 
>> store the value of d and can change the resulting output from the 
>> arithmetic.
>>
>> /* bug.c - to be run on linux since it hard-codes a binary 
>> representation of floating point number */
>> #include <stdio.h>
>> #include <stdlib.h>
>>
>> int main()
>> {
>> int val, new_val;
>> double d;
>> unsigned char *c = (unsigned char *)&d;
>> if(sizeof(d) != 8) {
>>   fprintf(stderr, "Wrong architecture\n");
>>   exit(1);
>> }
>> c[0] = 102;
>> c[1] = 102;
>> c[2] = 102;
>> c[3] = 38;
>> c[4] = 21;
>> c[5] = 197;
>> c[6] = 77;
>> c[7] = 64;
>>
>> printf("stage 1: d = %lf\n", d);
>> d *= 10.0;
>> /*printf("stage 2: d = %lf\n", d);*/
>> d = d * (1 << 16);
>> /*printf("stage 3: d = %lf\n", d);*/
>> val = (int)d;
>> printf("%d\n", val);
>> exit(0);
>> }
>>
>> -- Dave
>>
>> Oliver Rauch wrote:
>>     
>>> Am Dienstag, den 07.08.2007, 22:28 +1000 schrieb David Campbell:
>>>
>>>   
>>>       
>>>> This means that the current comparison "if (new_val != val)" in the 
>>>> xsane_back_gtk_value_update() function in xsane-back-gtk.c is invalid, 
>>>> because if there is the slightest difference in the floating point value 
>>>> (and there can be if the compiler has decided to implement the code 
>>>> optimally using processor registers), it will attempt to set the value 
>>>> again, and I'm seeing an infinite looping happening there because it 
>>>> never gets to the point where the values are the same!
>>>>     
>>>>         
>>> if (new_val != val) ...
>>>
>>> in general (and also in this case) is allowed.
>>> Please note that val and new_val are not floating point numbers in this code, they have the type SANE_Word (= int).
>>> So we have an integer comparison here.
>>>
>>> Please could you add some debug output to xsame-back-gtk.c after these lines:
>>>
>>>   xsane_back_gtk_set_option(opt_num, &val, SANE_ACTION_SET_VALUE);
>>>   xsane_control_option(xsane.dev, opt_num, SANE_ACTION_GET_VALUE, &new_val, 0);
>>> DBG(0, "val = %d, new_val = %d\n", val, new_val);
>>>
>>> and send a little trace of it when the infinit loop occurs.
>>>
>>>
>>> Best regards
>>> Oliver
>>>
>>>
>>>
>>>   
>>>       
>> -- 
>> sane-devel mailing list: sane-devel at lists.alioth.debian.org
>> http://lists.alioth.debian.org/mailman/listinfo/sane-devel
>> Unsubscribe: Send mail with subject "unsubscribe your_password"
>>              to sane-devel-request at lists.alioth.debian.org
>>     
>
>
>
>   



More information about the sane-devel mailing list