Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

StringMarshaler throws null reference exception #60

Open
maxxie85 opened this issue Nov 15, 2024 · 4 comments
Open

StringMarshaler throws null reference exception #60

maxxie85 opened this issue Nov 15, 2024 · 4 comments

Comments

@maxxie85
Copy link

I have a very strange exception happening on a client machine where I get a null reference exception.
The weird part is that the same program does run an similar machines but somehow this one is different.

XAE is 3.1.4024.62 (was .56)
The PLC is a CX9020 running on 3.1.4024.35

ADS library versions tried 6.1.290.0 and 6.1.298.0

Stack trace

System.NullReferenceException: Object reference not set to an instance of an object.
   at TwinCAT.TypeSystem.StringMarshaler..ctor(Encoding encoding, StringConvertMode mode)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler..ctor(Encoding encoding)
   at TwinCAT.TypeSystem.PrimitiveTypeMarshaler.get_Default()
   at TwinCAT.TypeSystem.SymbolicAnyTypeMarshaler..ctor(Encoding defaultValueEncoding)
   at TwinCAT.TypeSystem.InstanceValueMarshaler..ctor(Encoding defaultValueEncoding)
   at TwinCAT.ValueAccess.ValueFactory..ctor(ValueCreationModes mode)
   at TwinCAT.Ads.TypeSystem.SymbolLoaderFactory.createValueAccessor(IAdsConnection connection, SymbolLoaderSettings settings)
   at TwinCAT.Ads.TypeSystem.AdsSymbolServer.OnCreateLoader()
   at TwinCAT.Ads.TypeSystem.AdsSymbolServer.createLoader()
   at TwinCAT.Ads.TypeSystem.AdsSymbolServer.GetSymbolsAsync(CancellationToken cancel)
   at MPTCore.TwinCAT.Common.Services.CommunicationServiceBase.InitializeAsync(IAdsSession adsSession, CancellationToken cancellationToken, TimeSpan period) in C:\Source\GIT\MPTCore.TwinCAT\src\MPTCore.TwinCAT\Common\Services\CommunicationServiceBase.cs:line 98

It was a challenge to get the remote debugger attached and breaking at the right moment.
I think it's because the Encoding is null, but not to sure. I can't see any other details than in the picture below.

afbeelding

@RalfHeitmann
Copy link
Collaborator

Hi maxxie85, great analysis.
I think the ADS Default Encoding is not determined properly on that machine. Our Code:

        /// <summary>
        /// Gets the default encoding.
        /// </summary>
        /// <remarks>
        /// Since TwinCAT 4026, the UTF8 Encoding will be the default
        /// Historically in older TwinCAT installations, the Default encoding is ANSI with Windows active (e.g. CodePage 1252 (West-European))
        /// Because the AdsClient doesn't know what the actual communication partner is (4026 or older) we try to default to ANSI.
        /// The AdsClient holds its own actual encoding in SymbolNameEncoding/SymbolNameMarshaler with the (ADS) read settings from SymbolUploadInfo.
        /// </remarks>
        /// <value>The default encoding.</value>
        public static Encoding DefaultEncoding
        {
            get
            {
                // This returns the Windows Active Code Page on .NET Full Framework e.g. (ANSI 1252)
                // and UTF8 on .NET Core Systems!
                Encoding? ret = Encoding.Default;

#if NETSTANDARD2_0_OR_GREATER || NETCOREAPP3_1_OR_GREATER
                try
                {
                    // Trying to register the ANSI CodePage for .NET CORE
                    // see https://stackoverflow.com/questions/75803153/c-sharp-method-encoding-getencoding-wont-find-the-windows-1252-encoding
                    EncodingProvider provider = CodePagesEncodingProvider.Instance;
                    Encoding.RegisterProvider(provider);
                    // Because on .NET Core the Default Encoding is UTF8, which is not what we want for historical reasons.
                    ret = CodePagesEncodingProvider.Instance.GetEncoding(System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage);
                }
                catch (Exception)
                {
                    // Because have registered the Provider this shouldn't happen.

                    // see https://stackoverflow.com/questions/75803153/c-sharp-method-encoding-getencoding-wont-find-the-windows-1252-encoding
                    // UTF8 is the most appropriate in this case
                    //ret = Encoding.ASCII;
                    // As Fallback UTF8 is always better than ASCII because it supports more scenarios.
                    ret = Encoding.UTF8;
                }
#endif
                return ret;
            }
        }

This seem to return null in the case that the ANSICodePage is not installed. Why this is the case with your client machine - I don't now, but our implementation above isn't fully correct.
Probably you could find out, which Encoding/Codepage and operating system the client is running.

I will change the returned encoding to UTF8 for that case ...

@maxxie85
Copy link
Author

Hi Ralf,

Thanks for the quick response.
I have to double check the code page that's active on the machine. I have to make a new appointment with the client to gain remote access.

Another thing that might give some insight, I have reverted the application to a known working version.
This version is using ADS 6.1.203.
With the code snipped you shared, does it make sense it isn't working with ADS 6.1.290?

@RalfHeitmann
Copy link
Collaborator

The problem should be introduced with Version 2.1.286. Versions before that should work.

@RalfHeitmann
Copy link
Collaborator

6.1.304 contains a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants