Skip to content

Commit

Permalink
fix - Fixed "Fatal CLR Error" when dealing with arrays
Browse files Browse the repository at this point in the history
---

We've fixed random application exits and ExecutionEngineException errors with Fatal CLR Error when trying to get a list of supported decoders and a list of devices. This fix re-writes the ArrayVariableLength to be more resilient to problems and to avoid using a list of 256 pointers that point to random addresses.

---

Type: fix
Breaking: False
Doc Required: False
Part: 1/1
  • Loading branch information
AptiviCEO committed May 30, 2024
1 parent c174097 commit 788de88
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 16 deletions.
2 changes: 1 addition & 1 deletion BassBoom.Basolia/Devices/DeviceTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static ReadOnlyDictionary<string, string> GetDevices(string driver, ref s
{
// Query the devices
var handle = Mpg123Instance._out123Handle;
int devicesStatus = NativeOutputLib.out123_devices(handle, driver, ref names, ref descr, ref active);
int devicesStatus = NativeOutputLib.out123_devices(handle, driver, out names, out descr, ref active);
if (devicesStatus == (int)mpg123_errors.MPG123_ERR)
throw new BasoliaException("Can't query the devices", mpg123_errors.MPG123_ERR);
activeDevice = Marshal.PtrToStringAnsi(active);
Expand Down
21 changes: 7 additions & 14 deletions BassBoom.Basolia/Helpers/ArrayVariantLength.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,28 @@ namespace BassBoom.Basolia.Helpers
{
internal static class ArrayVariantLength
{
[StructLayout(LayoutKind.Sequential)]
internal struct ElementList
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)]
public IntPtr[] elements;
}

internal static string[] GetStringsKnownLength(IntPtr arrayPointer, int elements)
{
var stringsEnum = Marshal.PtrToStructure<ElementList>(arrayPointer);
List<string> strings = [];
for (int i = 0; i < elements; i++)
{
var element = stringsEnum.elements[i];
string value = Marshal.PtrToStringAnsi(element);
IntPtr elementPtr = Marshal.ReadIntPtr(arrayPointer, i * IntPtr.Size);
string value = Marshal.PtrToStringAnsi(elementPtr);
strings.Add(value);
}
return [.. strings];
}

internal static string[] GetStringsUnknownLength(IntPtr arrayPointer)
{
var stringsEnum = Marshal.PtrToStructure<ElementList>(arrayPointer);
List<string> strings = [];
foreach (var element in stringsEnum.elements)
for (int i = 0; i < int.MaxValue; i++)
{
if (element == IntPtr.Zero)
IntPtr elementPtr = Marshal.ReadIntPtr(arrayPointer, i * IntPtr.Size);
if (elementPtr == IntPtr.Zero)
break;
strings.Add(Marshal.PtrToStringAnsi(element));
string value = Marshal.PtrToStringAnsi(elementPtr);
strings.Add(value);
}
return [.. strings];
}
Expand Down
9 changes: 9 additions & 0 deletions BassBoom.Cli/CliBase/PlayerControls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,15 @@ BassBoom specifications
Basolia version: {{InitBasolia.BasoliaVersion}}
MPG123 version: {{InitBasolia.MpgLibVersion}}
OUT123 version: {{InitBasolia.OutLibVersion}}
Decoders
========
Supported decoders:
- {{string.Join("\n - ", DecodeTools.GetDecoders(true))}}
All decoders:
- {{string.Join("\n - ", DecodeTools.GetDecoders(false))}}
System specifications
=====================
Expand Down
9 changes: 9 additions & 0 deletions BassBoom.Cli/CliBase/RadioControls.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,15 @@ BassBoom specifications
MPG123 version: {{InitBasolia.MpgLibVersion}}
OUT123 version: {{InitBasolia.OutLibVersion}}
Decoders
========
Supported decoders:
- {{string.Join("\n - ", DecodeTools.GetDecoders(true))}}
All decoders:
- {{string.Join("\n - ", DecodeTools.GetDecoders(false))}}
System specifications
=====================
Expand Down
2 changes: 1 addition & 1 deletion BassBoom.Native/Interop/Output/NativeOutputLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ internal static unsafe class NativeOutputLib
/// </summary>
[DllImport(LibraryTools.LibraryNameOut, CharSet = CharSet.Ansi)]
internal static extern int out123_devices(out123_handle* ao,
[MarshalAs(UnmanagedType.LPStr)] string driver, ref nint names, ref nint descr, ref nint active_driver);
[MarshalAs(UnmanagedType.LPStr)] string driver, out nint names, out nint descr, ref nint active_driver);

/// <summary>
/// MPG123_EXPORT void out123_stringlists_free(char **name, char **descr, int count);
Expand Down

0 comments on commit 788de88

Please sign in to comment.