OK, here's a summarized gdb session. Sorry about the length, I hope it's
useful...
I set a breakpoint on xsane_option_menu_new() and wait for my menu-item of
interest (the source menu which should eventually contain "Flatbed" and
"Transparency Unit") to trigger. When the "Flatbed" menu item is created I
set a watchpoint on the memory pointed to by menu_list[].label (0xa57550):
(gdb) x/s 0xa57550
0xa57550: "Flatbed"
I then set a breakpoint on sane_control_option() and watch it get called on
several more option items with act=SANE_ACTION_GET_VALUE. The last couple
of calls are:
sane_control_option (h=0x9b5ec0, opt=0, act=SANE_ACTION_GET_VALUE
sane_control_option (h=0x9b5ec0, opt=2, act=SANE_ACTION_SET_VALUE
Right after this the memory watch point gets triggered and the original label
string gets stomped:
(gdb) x/s 0xa57550
0xa57550: "Àt¥"
Here's a truncated backtrace:
#0 0x00007fbc25b08e09 in _int_free () from /lib/libc.so.6
#1 0x00007fbc25b091ee in free () from /lib/libc.so.6
#2 0x00007fbc246ef680 in sanei_w_array (w=0x979978, len_ptr=0x7fff30bcee24,
v=0xa57530,
w_element=0x7fbc246ee440 <bin_w_byte>, element_size=1) at sanei_wire.c:181
#3 0x00007fbc246ee357 in bin_w_string (w=0x979978, v=0xa574c0) at
sanei_codec_bin.c:87
#4 0x00007fbc246ef66d in sanei_w_array (w=0x979978, len_ptr=0x7fff30bceea4,
v=0xa574a0,
w_element=0x7fbc246ee310 <bin_w_string>, element_size=8) at sanei_wire.c:178
#5 0x00007fbc246ef91e in sanei_w_option_descriptor (w=0x979978, v=0xa57470) at
sanei_wire.c:535
#6 0x00007fbc246ef30f in sanei_w_ptr (w=0x979978, v=0xa561e0,
w_value=0x7fbc246ef7c0 <sanei_w_option_descriptor>, value_size=56) at
sanei_wire.c:263
#7 0x00007fbc246ef431 in sanei_w_option_descriptor_ptr (w=0x979978,
v=0xa561e0) at sanei_wire.c:546
#8 0x00007fbc246ef66d in sanei_w_array (w=0x979978, len_ptr=0x9f03f0,
v=0x9f03f8,
w_element=0x7fbc246ef3f0 <sanei_w_option_descriptor_ptr>, element_size=8)
at sanei_wire.c:178
#9 0x00007fbc246ebd1b in fetch_options (s=0x9f03e0) at net.c:479
#10 0x00007fbc246ec2b3 in sane_net_get_option_descriptor (handle=0x9f03e0,
option=1) at net.c:1301
At this point the memory at 0xa57550 gets zeroed via memset, overwritten
with a different piece of the opt descriptor structure(*), zeroed, overwritten
with 'Flatbed' again, stomped again with some non-string data, zeroed with
memset, overwritten with another piece of the opt descriptor structure
(a different one than (*)), stomped with some non-string data, ... etc.
Eventually the memory activity started by the first sane_control_option(..
,act=SANE_ACTION_SET_VALUE, ..)
finishes. and the next break is at
sane_control_option (h=0x9b5ec0, opt=19, act=SANE_ACTION_SET_VALUE
The original menu_list[].label now points to this string:
(gdb) x/s 0xa57550
0xa57550: "Transparency Unit"
'Flatbed' is now stored at location 0xa57530.
Next, sane_control_option(opt=<> , act=SANE_ACTION_SET_VALUE, ..) is called
with several different opt values until it's called with opt=OPT_EQU_GROUP
and the memory stomping begins anew. When the memory stabilizes this time
menu_list[].label (0xa57550) points to 'Flatbed' again.
However, xsane_option_menu_new() gets called again for the Flatbed
option (second time):
xsane_option_menu_new (parent=0xaad540, str_list=0xa57530, val=0xad8c50
"Flatbed"
Note the updated str_list pointer is 0xa57530 (was 0xa57550 on the original
call). Shortly after this menu item is (re-)created, the data at 0xa57530
get walked over as above and is left pointing to garbage. Curiously,
0xa57550 is stable and still points to 'Flatbed'.
xsane_option_menu_new() gets called yet again for the Flatbed option (third
time):
xsane_option_menu_new (parent=0xaad540, str_list=0xa57530, val=0xad8c50
"Flatbed"
At this point 0xa57530 is garbage, 0xa57550 is still 'Flatbed'.
Now the GUI is initialized and ready to go. I set a breakpoint on
xsane_option_menu_callback() and change the scanner source menu option from
"Flatbed" to "Flatbed" to trigger the breakpoint. While stepping through
xsane_option_menu_callback() I get to this line:
opt = xsane_get_option_descriptor()
and the memory watchpoint triggers. At this point neither 0xa57530 nor
0xa57550 contain 'Flatbed' anymore (just NULLs or non-ascii bytes). Memory
churns again and by the time xsane_get_option_descriptor() exits 0xa57530
and 0xa57550 both point to data from a different part of the option
descriptor and neither contains the correct "Flatbed" string that should be
associated with the gtk menu_item.
Curiously the menu_list[].label value in the callback for the "Flatbed"
menu item is still 0xa57550, the pointer from the very first call of
xsane_option_menu_new(). I have no idea what the other two
xsane_option_menu_new(.., "Flatbed", ...) calls were for... Are there other
Source menus buried elsewhere in the GUI?
Anyway, the menu callback results in a request being passed to the epkowa
backend to change the source to "Sharpness" (in this instance) since that
is what 0xa57550 points to right now and the backend throws an error
because there is no "Sharpness" source. If I then try to change another
option (ie. Resolution), then there is more memory churn at 0xa57550 and
some different string (or garbage) will be sent to the backend on a
subsequent attempt to change the source to "Flatbed". If you whack on
enough options in the GUI then eventually you get "lucky" and the data at
0xa57550 in the option descriptor are back to "Flatbed" and the system
works.
When I dump the memory around 0xa57550 +- 512 bytes I see a real scamble
of option descriptor data. It looks like there are multiple copies of
various descriptors there too, offset by some tens of bytes. It really
looks like the memory pointed to by the network option descriptor is just a
temporary buffer, not a static structure. If I dump the data as strings
(ie. (gdb) x/512s 0xa57400) then I just set a bunch of trash with random
option-related substrings interspersed with non-ascii chars and NULLs.
What happens if you do the same thing using a non-epkowa driver over the
net backend? Do you get the same memory churn but the memory always ends
up being restored to the same state?
-- Brad
--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]