0

NUL character value inserted by logger before app crashes

I have a Xamarin Forms application running in Android 7.1, in which several objects have to concurrently write lines into a single shared file. So, I created the following class Log.cs, following the Microsoft documentation about the ReaderWriterLockSlim semaphore which is dedicated to conccurent access to shared file. Note that the project in which is included the Log class is a PCL project and the library used is PCLStorage, as I cannot use the System.IO namespace inside PCL project.

public sealed class Log
{
    private static string MyFileName = "MyPathToTheSharedFilename";
    private static ReaderWriterLockSlim _logFileLock = new ReaderWriterLockSlim();

    // The public async function used by all objects to write concurrently into file.
    public void WriteLog(
        string format,
        params object[] args)
    {
        Task.Run(() => WriteAsync(format, args));
    }

    // The private method which access the lock and actually write lines into the file
    private async Task WriteAsync(
        string format,
        params object[] args)
    {
        _logFileLock.EnterWriteLock();
        
        try
        {
            // Check whether the file exists.
            var logFileExists = await logFolder.CheckExistsAsync(MyFileName);
            IFile logFile = null;
            if (logFileExists == ExistenceCheckResult.NotFound)
                logFile = await logFolder.CreateFileAsync(MyFileName, CreationCollisionOption.OpenIfExists);
            else
                logFile = await logFolder.GetFileAsync(MyFileName);
            if (logFile == null)
                return;

            using (StreamWriter streamWriter = new StreamWriter(logFile.OpenAsync(FileAccess.ReadAndWrite).Result))
            {
                // Always append the text to write to the end of the file.
                streamWriter.BaseStream.Seek(0, SeekOrigin.End);
                streamWriter.WriteLine(string.Format(format, args));
                streamWriter.Flush();
            }
        }
        catch (Exception)
        {
               // I do not know what to do in case there is an exception, maybe try to create a new file???
        }
        finally
        {
            _logFileLock.ExitWriteLock();
        }
    }
}

And below is an example of use from another class:

public class AnotherClassWithNeedsToWriteToSharedFile
{
      private Log myLog = IoCService.Resolve<Log>(); // Resolve the singleton type Log.
      public WriteToTheSharedFile(string textToWrite)
      {
             myLog.WriteLog("{0:yyyy-MM-dd HH:mm:ss:fff}|{1}", DateTime.Now, "|Information|File");
      }
}

Everything works fine, I tested my code using Parallel.Foreach loops thoroughly, but in production, sometimes, I get a very long of several thousands of NULL character as depicted in the following screenshot I got, as if the log file could not actually write the text to the file, but after every such NULL line, my application crashes. No class that use the Log class writes NULL characters on purpose.

I would like to understand why and what makes the Log class write NULL characters like that, or at least how can I managed to find out?

Any suggestion or help will be highly appreciated. Thanks in advance.

J.Doe
  • 133
  • 6
  • why are you still using PCL? – Jason May 10 '23 at 16:21
  • Hi @Jason, it is a very old project, and migrating to .net standard project would take too much time. It is planned to migrate all PCL projects but for the moment, I cannot because of lack of time. – J.Doe May 10 '23 at 16:35
  • are you actually catching an exception? What is it? – Jason May 10 '23 at 16:37
  • I do not know because in the catch clause, I do not know what can I do , maybe create a file containing the exception message within it ? – J.Doe May 10 '23 at 16:40
  • Write it to a log file. Write it to the console. Use an exception logging tool. Display an error message in the app. etc... – Jason May 10 '23 at 16:41
  • OK I am gonna try to create a file within the catch clause, because as far as I know, there is no log library (NLog, log4net for instance) compatible with PCL project. I will let you know if I catch exception and if I managed to have the file with the exception. – J.Doe May 10 '23 at 16:43
  • Convert your PCL into a netstandard lib and use a proper logging tool instead of wasting time on rolling your own. – Cheesebaron May 11 '23 at 09:13

0 Answers0