Skip to content

Commit

Permalink
Add debug log.
Browse files Browse the repository at this point in the history
  • Loading branch information
birdinforest committed Aug 26, 2024
1 parent 0ee38b4 commit 1370d14
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 15 deletions.
127 changes: 112 additions & 15 deletions src/ClassicUO.Bootstrap/src/LibraryLoader.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace ClassicUO
{
Expand All @@ -17,24 +18,88 @@ static Native()
{
_loader = new UnixNativeLoader();
}
PrintSystemInfo();
}

private static void Log(string message)
{
Debug.WriteLine($"[Native Loader] {message}");
Console.WriteLine($"[Native Loader] {message}");
}

public static void PrintSystemInfo()
{
Log($"OS Description: {RuntimeInformation.OSDescription}");
Log($"OS Architecture: {RuntimeInformation.OSArchitecture}");
Log($"Framework Description: {RuntimeInformation.FrameworkDescription}");
Log($"Process Architecture: {RuntimeInformation.ProcessArchitecture}");
}

public static IntPtr LoadLibrary(string name)
{
return _loader.LoadLibrary(name);
try
{
Log($"Attempting to load library: {name}");
IntPtr handle = _loader.LoadLibrary(name);
Log($"Successfully loaded library: {name}, Handle: {handle}");
return handle;
}
catch (Exception ex)
{
Log($"Exception in LoadLibrary: {ex.Message}");
Log($"Stack trace: {ex.StackTrace}");
throw;
}
}

public static IntPtr GetProcessAddress(IntPtr module, string name)
{
return _loader.GetProcessAddress(module, name);
try
{
Log($"Getting process address for: {name} in module: {module}");
IntPtr address = _loader.GetProcessAddress(module, name);
if (address != IntPtr.Zero)
{
Log($"Successfully got process address for: {name}, Address: {address}");
}
else
{
Log($"Failed to get process address for: {name}");
}
return address;
}
catch (Exception ex)
{
Log($"Exception in GetProcessAddress: {ex.Message}");
Log($"Stack trace: {ex.StackTrace}");
throw;
}
}

public static int FreeLibrary(IntPtr module)
{
return _loader.FreeLibrary(module);
try
{
Log($"Freeing library: {module}");
int result = _loader.FreeLibrary(module);
if (result == 0)
{
Log($"Successfully freed library: {module}");
}
else
{
Log($"Failed to free library: {module}");
}
return result;
}
catch (Exception ex)
{
Log($"Exception in FreeLibrary: {ex.Message}");
Log($"Stack trace: {ex.StackTrace}");
throw;
}
}


abstract class NativeLoader
{
public abstract IntPtr LoadLibrary(string name);
Expand All @@ -45,6 +110,7 @@ abstract class NativeLoader
private class WinNativeLoader : NativeLoader
{
private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;

[DllImport("kernel32.dll", SetLastError = true)]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private static extern IntPtr LoadLibraryExW([MarshalAs(UnmanagedType.LPWStr)] string lpLibFileName, IntPtr hFile, uint dwFlags);
Expand All @@ -55,7 +121,6 @@ private class WinNativeLoader : NativeLoader
[DllImport("kernel32", EntryPoint = "FreeLibrary")]
private static extern int FreeLibrary_WIN(IntPtr module);


public override IntPtr LoadLibrary(string name)
{
return LoadLibraryExW(name, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
Expand All @@ -74,10 +139,8 @@ public override int FreeLibrary(IntPtr module)

private class UnixNativeLoader : NativeLoader
{

public const int RTLD_NOW = 0x002;


private static class Libdl1
{
private const string LibName = "libdl";
Expand All @@ -92,7 +155,7 @@ private static class Libdl1
public static extern int dlclose(IntPtr handle);

[DllImport(LibName)]
public static extern int dlerror();
public static extern IntPtr dlerror();
}

private static class Libdl2
Expand All @@ -109,37 +172,71 @@ private static class Libdl2
public static extern int dlclose(IntPtr handle);

[DllImport(LibName)]
public static extern int dlerror();
public static extern IntPtr dlerror();
}

private static bool m_useLibdl1;

static UnixNativeLoader()
{
try
{
Libdl1.dlerror();
m_useLibdl1 = true;
Log("Using libdl1 for dynamic loading");
}
catch
{
m_useLibdl1 = false;
Log("Using libdl2 for dynamic loading");
}
}

private static bool m_useLibdl1;

public override IntPtr LoadLibrary(string name)
{
return m_useLibdl1? Libdl1.dlopen(name, RTLD_NOW) : Libdl2.dlopen(name, RTLD_NOW);
Log($"Attempting to load library: {name}");
var handle = m_useLibdl1 ? Libdl1.dlopen(name, RTLD_NOW) : Libdl2.dlopen(name, RTLD_NOW);
if (handle == IntPtr.Zero)
{
var error = m_useLibdl1 ? Libdl1.dlerror() : Libdl2.dlerror();
Log($"Failed to load library: {name}, Error: {Marshal.PtrToStringAnsi(error)}");
throw new Exception($"Failed to load library: {name}, Error: {Marshal.PtrToStringAnsi(error)}");
}
Log($"Successfully loaded library: {name}, Handle: {handle}");
return handle;
}

public override IntPtr GetProcessAddress(IntPtr module, string name)
{
return m_useLibdl1 ? Libdl1.dlsym(module, name) : Libdl2.dlsym(module, name);
Log($"Getting process address for: {name} in module: {module}");
var address = m_useLibdl1 ? Libdl1.dlsym(module, name) : Libdl2.dlsym(module, name);
if (address == IntPtr.Zero)
{
var error = m_useLibdl1 ? Libdl1.dlerror() : Libdl2.dlerror();
Log($"Failed to get process address for: {name}, Error: {Marshal.PtrToStringAnsi(error)}");
}
else
{
Log($"Successfully got process address for: {name}, Address: {address}");
}
return address;
}

public override int FreeLibrary(IntPtr module)
{
return m_useLibdl1 ? Libdl1.dlerror() : Libdl2.dlerror();
Log($"Freeing library: {module}");
var result = m_useLibdl1 ? Libdl1.dlclose(module) : Libdl2.dlclose(module);
if (result != 0)
{
var error = m_useLibdl1 ? Libdl1.dlerror() : Libdl2.dlerror();
Log($"Failed to free library: {module}, Error: {Marshal.PtrToStringAnsi(error)}");
}
else
{
Log($"Successfully freed library: {module}");
}
return result;
}
}
}
}
}
9 changes: 9 additions & 0 deletions src/ClassicUO.Bootstrap/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,19 @@ public void Run(string[] args)
}

var libPtr = Native.LoadLibrary(libName);
if (libPtr == IntPtr.Zero)
{
throw new Exception($"Failed to load library: {libName}");
}

unsafe
{
var initializePtr = Native.GetProcessAddress(libPtr, "Initialize");
if (initializePtr == IntPtr.Zero)
{
throw new Exception($"Failed to get function pointer for Initialize in library: {libName}");
}

var initializeMethod = Marshal.GetDelegateForFunctionPointer<dOnInitializeCuo>(initializePtr);

var argv = new IntPtr[args.Length];
Expand Down

0 comments on commit 1370d14

Please sign in to comment.