FS#12639 - Certain themes cause the WPS to not load properly and USB to not work

Attached to Project: Rockbox
Opened by Ludovic Jacques (lebellium) - Sunday, 08 April 2012, 10:27 GMT
Last edited by Alex Parker (BigBambi) - Sunday, 27 January 2013, 22:53 GMT
Task Type Bugs
Category Themes
Status Unconfirmed   Reopened
Assigned To Jonathan Gordon (jdgordon)
Operating System Sansa AMSv2
Severity Low
Priority Normal
Reported Version Daily build (which?)
Due in Version Undecided
Due Date Undecided
Percent Complete 0%
Votes 0
Private No


Both issues seem to appear with any version of my theme and with any build.
Let's try it with the latest version 1.30 of my theme (in attachment but also here: ) and a recent build (I use version: 0c4bd3a-120406)

-Theme loading

When you load the theme for the 1st time, the WPS will never load properly (failsafe). The workaround is to turn off the device and turn it on again and then the WPS will always load properly until you reload the theme for some reasons (trying another theme and revert back to mine etc).
I tried both with the full theme version and this "light" version of WPS:

-USB connection (tested on Windows 7, with or without a microSD, and there isn't such an issue with the other themes)

If I plug the USB cable while the player is on or off, it will almost never mount properly.
Usually the USB screen appears on my SBS, the computer recognizes a USB device is connected but either nothing appears in "my computer" or the device appears but is not accessible. When I unplug the USB cable, the Zip gets stuck on the USB screen and only reset can turn it off.
Sometimes it even displays some erros like that when plugging the USB cable: "data abort at 30FSR 0x8 (domain 0, fault address 0x964176 bt pc: 0x3006AC3 bt end" , sometimes it doesn't display the USB on SBS but gets stuck on the main menu.
And rarely in the same conditions it also mounts properly...

Like for WPS, I made a "light" version of SBS without the status bar and that way the Zip seems to mount and unmout properly every time!
So maybe a tag in the status bar causes the issue with USB connection?
This task depends upon

Comment by Rafaël Carré (funman) - Monday, 30 April 2012, 21:48 GMT
I built a ClipZip simulator with SDL threads:

./configure --sdl-threads

When the build fails, I add firmware/asm/ffs.o to the command line that failed (make V=1)

after make install and unzip -oq -d simdisk ~/ :

valgrind --db-attach=yes ./rockboxui

load the lebellium theme:

==10128== Conditional jump or move depends on uninitialised value(s)
==10128== at 0x451B5F: buflibmove_callback (font.c:120)
==10128== by 0x44A305: move_block (buflib.c:217)
==10128== by 0x44A409: buflib_compact (buflib.c:294)
==10128== by 0x44A837: buflib_compact_and_shrink (buflib.c:325)
==10128== by 0x44AAAF: buflib_alloc_ex (buflib.c:515)
==10128== by 0x44AD59: core_alloc_ex (core_alloc.c:62)
==10128== by 0x42D9BB: load_skin_bmp (skin_parser.c:1696)
==10128== by 0x42DFDA: skin_data_load (skin_parser.c:1751)
==10128== by 0x42AF1E: skin_load (skin_engine.c:174)
==10128== by 0x42B078: skin_get_gwps (skin_engine.c:270)
==10128== by 0x42B138: settings_apply_skins (skin_engine.c:154)
==10128== by 0x41869F: settings_load_config (settings.c:370)
==10128== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- Y

0x0000000000451b5f in buflibmove_callback (handle=13, current=0x8ddff0, new=<optimized out>)
at /home/fun/rockbox/firmware/font.c:120
120 UPDATE(alloc->font.cache._index);
(gdb) print alloc
$1 = (struct buflib_alloc_data *) 0x8ddff0
(gdb) print alloc->font.cache._index
$2 = (short int *) 0x597dfa0
(gdb) print alloc->font.cache
$3 = {_lru = {_head = 17388, _tail = 67, _size = 0, _slot_size = 0, _base = 0xffffffff},
_size = 0, _capacity = 0, _prev_char_code = 512, _prev_result = 0, _index = 0x597dfa0}
(gdb) q

(no clue on how to debug that one)

Then press u to mount USB
Then press u again to unmount USB:
All threads have acknowledged the connect.
usb: got ack, 0 to go...
font id must be >= 2
font id must be >= 2
==10128== Invalid read of size 1
==10128== at 0x56F9560: __strchr_sse42 (strchr.S:89)
==10128== by 0x42BCB2: parse_font_load (skin_parser.c:487)
==10128== by 0x42B948: skin_element_callback (skin_parser.c:2151)
==10128== by 0x45CD57: skin_parse_tag (skin_parser.c:812)
==10128== by 0x45D209: skin_parse_line_optional (skin_parser.c:372)
==10128== by 0x45D6B5: skin_parse (skin_parser.c:279)
==10128== by 0x42DEB7: skin_data_load (skin_parser.c:2296)
==10128== by 0x42AF1E: skin_load (skin_engine.c:174)
==10128== by 0x42B078: skin_get_gwps (skin_engine.c:270)
==10128== by 0x42B138: settings_apply_skins (skin_engine.c:154)
==10128== by 0x4437B2: gui_usb_screen_run (usb_screen.c:332)
==10128== by 0x40D488: default_event_handler_ex (misc.c:549)
==10128== Address 0x1a0000008eaca8 is not stack'd, malloc'd or (recently) free'd
==10128== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ---- Y
__strchr_sse42 () at ../sysdeps/x86_64/multiarch/strchr.S:89
89 ../sysdeps/x86_64/multiarch/strchr.S: Aucun fichier ou dossier de ce type.
(gdb) up
#1 0x000000000042bcb3 in parse_font_load (element=<optimized out>, token=<optimized out>,
wps_data=<optimized out>) at /home/fun/rockbox/apps/gui/skin_engine/skin_parser.c:487
487 ptr = strchr(filename, '.');
(gdb) print filename
$1 = 0x1a0000008eaca8 <Address 0x1a0000008eaca8 out of bounds>
(gdb) print element
$2 = <optimized out>
(gdb) print token
$3 = <optimized out>
(gdb) print wps_data
$4 = <optimized out>
(gdb) up
#2 0x000000000042b949 in skin_element_callback (element=0x6b7b50, data=0x749788)
at /home/fun/rockbox/apps/gui/skin_engine/skin_parser.c:2151
2151 if (function(element, token, wps_data) < 0)
(gdb) print element
$5 = (struct skin_element *) 0x6b7b50
(gdb) print *element
$6 = {next = -1, children = 20450229081866240, data = -2306272, tag = 0x48a760,
params = 1892, children_count = 0, line = 20, type = TAG, params_count = 2 '\002'}
(gdb) print element.children
$7 = 20450229081866240

Comment by Rafaël Carré (funman) - Thursday, 03 May 2012, 04:21 GMT
(gdb) frame
#1 0x000000000043c626 in parse_font_load (element=0x6edb10, token=0x6edb88,
wps_data=0x77f928) at /home/fun/rockbox/apps/gui/skin_engine/skin_parser.c:487
487 ptr = strchr(filename, '.');

filename is defined on:

char *filename = get_param_text(element, 1);


static inline char*
get_param_text(struct skin_element *element, int param_number)
struct skin_tag_parameter* params = SKINOFFSETTOPTR(skin_buffer, element->params);
return SKINOFFSETTOPTR(skin_buffer, params[param_number].data.text);

(gdb) print ((struct skin_tag_parameter*)(&skin_buffer[element->params]))[1]
$75 = {type = INTEGER, data = {number = 0, text = 7318349394477056, code = 7318349394477056},
type_code = 4 '\004'}
(gdb) print ((struct skin_tag_parameter*)(&buffer_start[element->params]))[1]
$76 = {type = STRING, data = {number = 1940, text = 1940, code = 1940}, type_code = 70 'F'}
(gdb) print (char*)(&buffer_start[1940])
$77 = 0x6edb78 "08-Fixed.fnt"

(gdb) print skin_buffer
$78 = 0x92d440 "(\003"
(gdb) print buffer_start
$79 = (unsigned char *) 0x6ed3e4 "\377\377\377\377\377\377\377\377"
(gdb) print buffer_front

skin_buffer and buffer_start seem to not be set to the same thing

buffer_start is in bss and skin_buffer in audiobuffer
Comment by Rafaël Carré (funman) - Thursday, 03 May 2012, 04:35 GMT
Allocation is made here:

(gdb) frame 3
#3 0x0000000000486807 in skin_parse_tag (element=0x6edb10, document=0x7fefff7c0)
at /home/fun/rockbox/lib/skin_parser/skin_parser.c:812
812 if (callback(element, callback_data) == CALLBACK_ERROR)
(gdb) print params[1]
$4 = {type = STRING, data = {number = 1940, text = 1940, code = 1940}, type_code = 70 'F'}

line 801: element->params = skin_buffer_to_offset(params);
skin_buffer_to_offset() references buffer_start, which was set to skin_buffer by skin_buffer_init()

When params is used in parse_font_load(), skin_buffer has changed.
Comment by Rafaël Carré (funman) - Tuesday, 08 May 2012, 00:09 GMT
This patch is needed to build the sim with --sdl-threads

--sdl-threads is MANDATORY for valgrind
Comment by Rafaël Carré (funman) - Thursday, 10 May 2012, 11:34 GMT
lib/skin_parser/skin_parser.c:801 element->params = skin_buffer_to_offset(params);

skin_buffer_to_offset() use buffer_start relative offset (buffer_start is internal to lib/skin_parser)

apps/gui/skin_engines/skin_parser.c:397 filename = get_param_text(element, 1);

get_param_text() use SKINOFFSETPTR(skin_buffer, elements->param), skin_buffer is internal to apps/gui/skin_engine

The 2 buffers (internal to each folder) are unsynchronized -> boom we are now reading random memory
Comment by Rafaël Carré (funman) - Thursday, 10 May 2012, 12:04 GMT Comment by Raza (DebianUser) - Sunday, 27 January 2013, 22:53 GMT
I have a similar problem but just that the theme is breaking the USB.
Comment by Raza (DebianUser) - Sunday, 27 January 2013, 22:54 GMT
Woops, posted the wrong link.
Comment by Raza (DebianUser) - Sunday, 27 January 2013, 23:02 GMT
Bug report that I filed in the other task:

I've tried Ignus and Rayborraido_ypr0 and both fail to connect to USB. I always get memory error. The only theme that I can use to connect to USB is Cabbie.

I'm currently using the latest build from the 27th of January 2013.

This is the error I get on the screen with Ignus theme applied:

data abort at 6002DE30.
FSR 0x1 (Domain 0, Fault 1)
address: 0x602026CDA
pc: 6002DE30 sp: 600AC9D0
A: 6002A030
A: 60027E88
A: 60028AE4
A: 6004A850
A: 600009F0
A: 60000DB4
A: 60043EFC
A: 60044254
bt end
Comment by Rafaël Carré (funman) - Monday, 28 January 2013, 01:42 GMT
Tested fuze+ sim with RAYBORADIO (you made the same typo 2 times)

configured with --sdl-threads

Pressing u 2 times (plug, then unplug)

USB inserted. Waiting for 6 acks...
usb: got ack, 5 to go...
usb: got ack, 4 to go...
usb: got ack, 3 to go...
usb: got ack, 2 to go...
usb: got ack, 1 to go...
All threads have acknowledged the connect.
usb: got ack, 0 to go...
==26664== Thread 1:
==26664== Conditional jump or move depends on uninitialised value(s)
==26664== at 0x45413C: buflibmove_callback (font.c:113)
==26664== by 0x44C686: move_block (buflib.c:225)
==26664== by 0x44C88F: buflib_compact (buflib.c:307)
==26664== by 0x44CCF2: buflib_compact_and_shrink (buflib.c:338)
==26664== by 0x44CF74: buflib_alloc_ex (buflib.c:528)
==26664== by 0x44D1DD: core_alloc (core_alloc.c:57)
==26664== by 0x42FE14: skin_data_load (skin_parser.c:2422)
==26664== by 0x42C8DD: skin_load (skin_engine.c:176)
==26664== by 0x42CA43: skin_get_gwps (skin_engine.c:274)
==26664== by 0x42CB0B: settings_apply_skins (skin_engine.c:156)
==26664== by 0x445914: gui_usb_screen_run (usb_screen.c:333)
==26664== by 0x40D9B5: default_event_handler_ex (misc.c:556)
==26664== ---- Attach to debugger ? --- [Return/N/n/Y/y/C/c] ----
Comment by Tiago Medeiros (madcat1990) - Thursday, 15 August 2013, 14:40 GMT
I can confirm this bug.

I've been having USB problems with my Clip+, I would do a basic transfer (File-heavy) and after a while the device would simply freeze. USB devices shown on my computer were completely empty.

After switching to a failsafe theme of rockbox, not only did windows detect my device a whole lot faster, but I somehow gained 2MB/s of xfer rate.

I was told on IRC to report my findings, and these are it.

P.S: After 3 transfers, it seems to still be working fine! :O