Update. I ran the test app in the Xcode debugger. I may have found the problem. A parameter gets corrupted during initialization.
Yesterday's HEAD from git. Tracing in:
Code: Select all
#0 0x10014aeab in var_SetAddress [inlined] at vlc_variables.h:275
#1 0x10014aeab in libvlc_media_player_set_nsobject at media_player.c:842
#2 0x100011db4 in -[VLCMediaPlayer setDrawable:] at VLCMediaPlayer.m:256
#3 0x100013d8c in -[VLCMediaPlayer(Private) initWithDrawable:] at VLCMediaPlayer.m:731
#4 0x1000118fa in -[VLCMediaPlayer initWithVideoView:] at VLCMediaPlayer.m:194
#5 0x100000f67 in -[Controller awakeFromNib] at Controller.m:28
The setDrawable accessor calls libvlc_media_player_set_nsobject(). The pointers instance and aDrawable are valid at this point. The function libvlc_media_player_set_nsobject() passes on the drawable information (here's the whole function; __APPLE__ is defined):
Code: Select all
void libvlc_media_player_set_nsobject( libvlc_media_player_t *p_mi,
void * drawable )
{
assert (p_mi != NULL);
#ifdef __APPLE__
var_SetAddress (p_mi, "drawable-nsobject", drawable);
#else
(void) p_mi; (void)drawable;
#endif
}
Again, the pointers p_mi and drawable are valid. Note that we also pass in a const char* "drawable-nsobject" denoting the name of the VLC property (for lack of a better name) that is being set.
The function var_SetAddress() (in vlc_variables.h) is simple enough:
Code: Select all
static inline
int var_SetAddress( vlc_object_t *p_obj, const char *psz_name, void *ptr )
{
vlc_value_t val;
val.p_address = ptr;
return var_SetChecked( p_obj, psz_name, VLC_VAR_ADDRESS, val );
}
Tracing into the var_SetChecked() line, the call stack changes to:
Code: Select all
#0 0x10014f448 in dyld_stub_var_SetChecked
#1 0x100011db4 in -[VLCMediaPlayer setDrawable:] at VLCMediaPlayer.m:256
#2 0x100013d8c in -[VLCMediaPlayer(Private) initWithDrawable:] at VLCMediaPlayer.m:731
#3 0x1000118fa in -[VLCMediaPlayer initWithVideoView:] at VLCMediaPlayer.m:194
#4 0x100000f67 in -[Controller awakeFromNib] at Controller.m:28
The dyld_stub_ prefix sounds like something is getting dynamically loaded at this point...
Stepping in again, we get:
Code: Select all
#0 0x1000bb890 in var_SetChecked at variables.c:710
#1 0x100011db4 in -[VLCMediaPlayer setDrawable:] at VLCMediaPlayer.m:256
#2 0x100013d8c in -[VLCMediaPlayer(Private) initWithDrawable:] at VLCMediaPlayer.m:731
#3 0x1000118fa in -[VLCMediaPlayer initWithVideoView:] at VLCMediaPlayer.m:194
#4 0x100000f67 in -[Controller awakeFromNib] at Controller.m:28
Now something weird happens. The parameter psz_name gets corrupted before the actual function body of var_SetChecked() is entered. It looks like there's something going on behind the scenes. Thus, var_SetChecked() never gets the information that it was the "drawable-nsobject" that the caller wanted to set. The line
Code: Select all
p_var = Lookup( p_this, psz_name );
then returns NULL, and the drawable pointer never reaches the player. I suspect this is causing the blank white video output.
The code being run at this point is the following. C and disassembly provided. I've added numbers at the beginning of the C lines, corresponding to the numbers at the end of the lines in the disassembly.
Code: Select all
3 | int var_SetChecked( vlc_object_t *p_this, const char *psz_name,
2 | int expected_type, vlc_value_t val )
1 | {
4 | int i_ret = VLC_SUCCESS;
| variable_t *p_var;
| vlc_value_t oldval;
|
| // ...etc...
Disassembly:
Code: Select all
0x00000001000bb890 <+0000> push %rbp <--- 1, beginning of call
0x00000001000bb891 <+0001> mov %rsp,%rbp
0x00000001000bb894 <+0004> push %r15
0x00000001000bb896 <+0006> push %r14
0x00000001000bb898 <+0008> push %r13
0x00000001000bb89a <+0010> push %r12
0x00000001000bb89c <+0012> push %rbx
0x00000001000bb89d <+0013> sub $0x38,%rsp
0x00000001000bb8a1 <+0017> mov %edx,%ebx
0x00000001000bb8a3 <+0019> mov %rsi,-0x60(%rbp) <--- 2, executing this instruction corrupts psz_name
0x00000001000bb8a7 <+0023> mov %rdi,%r14 <--- 3, now psz_name is corrupt but other parameters are fine
0x00000001000bb8aa <+0026> mov %rcx,-0x50(%rbp) <--- 4, function body entered
0x00000001000bb8ae <+0030> test %r14,%r14
0x00000001000bb8b1 <+0033> je 0x1000bba34 <var_SetChecked+420>
Specifically speaking, on the line marked "2", the memory address that psz_name points to gets changed. Originally it is, for example, 0x1001505d1, and after the line it becomes 0x7fff5fbfef20 (both actual numbers from a debug trace). According to the debugger, the new address contains garbage data (random-looking bytes).
Forcing the original address back using the debugger causes EXC_BAD_ACCESS, so I assume a remapping is indeed supposed to take place - but for some reason, it fails to work properly.
The question now is, what exactly happens here? I built the VLC library from these exact sources, so it can't be a version mismatch between the headers and the lib. A bug in the optimizer is not possible, either, since this is a debug build.
So, I guess this boils down to two possibilities:
- My build of VLC is still somehow broken (but how?)
- Something has changed in OS X 10.6.5, causing the breakage.
Any suggestions?