locked
Why does a Slider ValueChanged handler read from address 0 when accessing this->mySlider->Value ?

    Question

  • So I have this XAML:

            <Slider Name="mySlider" Width="500" Value="250" ValueChanged="Slider_ValueChanged_1" ></Slider>

    And this is the handler:

    void SliderChangeApp::MainPage::Slider_ValueChanged_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
    {
    	double newValue= this->mySlider->Value;
    }
    

    And the result is a read of address 0x00000000 causing an exception on the read of Value.

    The debugger reports:

    -		mySlider	0x00000000 {__abi_baseclass=??? }	Windows::UI::Xaml::Controls::Slider ^
    -		Windows::UI::Xaml::Controls::Primitives::RangeBase	{__abi_baseclass=??? }	Windows::UI::Xaml::Controls::Primitives::RangeBase
    +		Windows::UI::Xaml::Controls::Control	{__abi_baseclass=??? }	Windows::UI::Xaml::Controls::Control
    +		Windows::UI::Xaml::Controls::Primitives::IRangeBase	{...}	Windows::UI::Xaml::Controls::Primitives::IRangeBase
    +		Windows::UI::Xaml::Controls::Primitives::IRangeBaseOverrides	{...}	Windows::UI::Xaml::Controls::Primitives::IRangeBaseOverrides
    		__abi_baseclass	<Unable to read memory>	
    -		Windows::UI::Xaml::Controls::ISlider	{...}	Windows::UI::Xaml::Controls::ISlider
    -		Platform::Object	{...}	Platform::Object
    		__vfptr	<Unable to read memory>	void * *
    		__abi_baseclass	<Unable to read memory>	
    

    Does anybody understand what went wrong?

    The call stack is:

    >	SliderChangeApp.exe!SliderChangeApp::MainPage::Slider_ValueChanged_1(Platform::Object ^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^ e) Line 43	C++
     	SliderChangeApp.exe!`Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventHandler::RangeBaseValueChangedEventHandler<SliderChangeApp::MainPage,void (__cdecl SliderChangeApp::MainPage::*)(Platform::Object ^,Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^)>'::`3'::__abi_PointerToMemberWeakRefCapture::Invoke(Platform::Object ^ __param0, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^ __param1)	C++
     	SliderChangeApp.exe!Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventHandler::Invoke(Platform::Object ^ __param0, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^ __param1)	C++
     	SliderChangeApp.exe!Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventHandler::[Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventHandler::__abi_IDelegate]::__abi_Windows_UI_Xaml_Controls_Primitives_RangeBaseValueChangedEventHandler___abi_IDelegate____abi_Invoke(Platform::Object ^ __param0, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs ^ __param1)	C++
     	Windows.UI.Xaml.dll!5d468c35()	Unknown
     	[Frames below may be incorrect and/or missing, no symbols loaded for Windows.UI.Xaml.dll]	
     	Windows.UI.Xaml.dll!5d572b00()	Unknown
     	Windows.UI.Xaml.dll!5d91381f()	Unknown
     	Windows.UI.Xaml.dll!5d56ecca()	Unknown
     	Windows.UI.Xaml.dll!5d5700f4()	Unknown
     	Windows.UI.Xaml.dll!5d56ffa1()	Unknown
     	Windows.UI.Xaml.dll!5d421f38()	Unknown
     	Windows.UI.Xaml.dll!5d421e86()	Unknown
     	Windows.UI.Xaml.dll!5d421d8d()	Unknown
     	Windows.UI.Xaml.dll!5d457a49()	Unknown
     	Windows.UI.Xaml.dll!5d457b07()	Unknown
     	Windows.UI.Xaml.dll!5d45ace3()	Unknown
     	Windows.UI.Xaml.dll!5d45829c()	Unknown
     	Windows.UI.Xaml.dll!5d4df1b9()	Unknown
     	Windows.UI.Xaml.dll!5d446d5a()	Unknown
     	Windows.UI.Xaml.dll!5d3795dc()	Unknown
     	Windows.UI.Xaml.dll!5d446529()	Unknown
     	Windows.UI.Xaml.dll!5d4f42ba()	Unknown
     	008de078()	Unknown
     	Windows.UI.Xaml.dll!5d5d5180()	Unknown
     	Windows.UI.Xaml.dll!5d5d5016()	Unknown
     	Windows.UI.Xaml.dll!5d5d4f77()	Unknown
     	Windows.UI.Xaml.dll!5d5d4eaa()	Unknown
     	Windows.UI.Xaml.dll!5d5d4927()	Unknown
     	SliderChangeApp.exe!Windows::UI::Xaml::IApplicationStatics::LoadComponent(Platform::Object ^ __param0, Windows::Foundation::Uri ^ __param1, Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation __param2)	C++
     	SliderChangeApp.exe!Windows::UI::Xaml::Application::LoadComponent(Platform::Object ^ __param0, Windows::Foundation::Uri ^ __param1, Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation __param2)	C++
     	SliderChangeApp.exe!SliderChangeApp::MainPage::[SliderChangeApp::__IMainPagePublicNonVirtuals]::InitializeComponent() Line 26	C++
     	SliderChangeApp.exe!SliderChangeApp::MainPage::MainPage() Line 26	C++
    

    It seems to me that if the framework is going to send a ValueChanged event, that the slider should already be initialized.

    This was reported on July 8th, but I have no feedback yet.

    https://connect.microsoft.com/VisualStudio/feedback/details/752839/using-value-250-causes-crash-in-valuechanged-c-handler-of-a-slider

    Tuesday, July 24, 2012 2:26 AM

Answers

  • Right, so it looks like the guidance should be to write the handler like:

    void SliderChangeApp::MainPage::Slider_ValueChanged_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
    {
    	if ( nullptr != mySlider ) {
    		double newValue= this->mySlider->Value;
    	}
    }
    

     

     

    • Proposed as answer by Jesse Jiang Wednesday, July 25, 2012 7:47 AM
    • Marked as answer by Andrew7Webb Wednesday, July 25, 2012 3:13 PM
    Wednesday, July 25, 2012 12:03 AM

All replies

  • Have you tried setting the slider value to start with ?

    n.Wright

    Tuesday, July 24, 2012 10:01 PM
  • I don't get a chance because Slider_ValueChanged_1 is called as the generated code executes LoadComponent:

    void MainPage::InitializeComponent()
    {
        if (_contentLoaded)
            return;
    
        _contentLoaded = true;
    
        // Call LoadComponent on ms-appx:///MainPage.xaml
        Windows::UI::Xaml::Application::LoadComponent(this, ref new Windows::Foundation::Uri(L"ms-appx:///MainPage.xaml"), Windows::UI::Xaml::Controls::Primitives::ComponentResourceLocation::Application);
    
        // Get the Slider named 'mySlider'
        mySlider = safe_cast<Windows::UI::Xaml::Controls::Slider^>(static_cast<Windows::UI::Xaml::IFrameworkElement^>(this)->FindName(L"mySlider"));
    }
    Come to think of it, since mySlider looks like it is initialized AFTERWARDS, this probably explains the problem. There is a false assumption being made that LoadComponent won't actually use mySlider. But since it does the code crashes.

    Perhaps there is a race condition that triggers because my graphics (Name Intel(R) HD Graphics Family (Microsoft Corporation - WDDM 1.2) are slow?

    In fact, if I "run to cursor" with the cursor on mySlider = safe_cast ... , I get the exception first.



    • Edited by Andrew7Webb Tuesday, July 24, 2012 10:22 PM report results of break on mySlider =
    Tuesday, July 24, 2012 10:19 PM
  • I was going to suggest a race.

    You cant read the value if the component doesnt exist yet.

    I have a C++ USB 6 channel audio mixer that uses sliders and that works fine.


    n.Wright


    Tuesday, July 24, 2012 10:28 PM
  • If you single step through InitializeComponent() with a Slider that has XAML:

     <Slider Name="mySlider" Width="500" Value="250" ValueChanged="Slider_ValueChanged_1" ></Slider>

    does your ValueChanged handler get called before your slider is initialized?

    (It is crucial that the XAML has a Value="250" to trigger the handler prematurely.)

    Tuesday, July 24, 2012 11:35 PM
  • I dont use XAML in my code its just a windows forms app.

    My code just sets a flag if the slider value changes and the main code has a timer running that reads the sliders if it sees the flag has changed and sends the new values via USB to the mixer.


    n.Wright

    Tuesday, July 24, 2012 11:39 PM
  • Right, so it looks like the guidance should be to write the handler like:

    void SliderChangeApp::MainPage::Slider_ValueChanged_1(Platform::Object^ sender, Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs^ e)
    {
    	if ( nullptr != mySlider ) {
    		double newValue= this->mySlider->Value;
    	}
    }
    

     

     

    • Proposed as answer by Jesse Jiang Wednesday, July 25, 2012 7:47 AM
    • Marked as answer by Andrew7Webb Wednesday, July 25, 2012 3:13 PM
    Wednesday, July 25, 2012 12:03 AM