diff --git a/src/Ultra.Sampler/MacOS/NativeModuleEvent.cs b/src/Ultra.Sampler/MacOS/NativeModuleEvent.cs index 7d1ec21..cf62a25 100644 --- a/src/Ultra.Sampler/MacOS/NativeModuleEvent.cs +++ b/src/Ultra.Sampler/MacOS/NativeModuleEvent.cs @@ -2,6 +2,8 @@ // Licensed under the BSD-Clause 2 license. // See license.txt file in the project root for full license information. +using System.Text; + namespace Ultra.Sampler.MacOS; internal struct NativeModuleEvent @@ -13,6 +15,6 @@ internal struct NativeModuleEvent public override string ToString() { - return $"{nameof(LoadAddress)}: 0x{LoadAddress:X8}, {nameof(Path)}: {Path}, {nameof(TimestampUtc)}: {TimestampUtc:O}"; + return $"{nameof(LoadAddress)}: 0x{LoadAddress:X8}, {nameof(Path)}: {Encoding.UTF8.GetString(Path ?? [])}, {nameof(TimestampUtc)}: {TimestampUtc:O}"; } } \ No newline at end of file diff --git a/src/Ultra.Sampler/Ultra.Sampler.csproj b/src/Ultra.Sampler/Ultra.Sampler.csproj index 7fb9d57..18a3280 100644 --- a/src/Ultra.Sampler/Ultra.Sampler.csproj +++ b/src/Ultra.Sampler/Ultra.Sampler.csproj @@ -6,6 +6,11 @@ enable true false + true + libUltraSampler + true + <_SuppressNativeLibEventSourceWarning>true + true diff --git a/src/Ultra.Sampler/build_native.sh b/src/Ultra.Sampler/build_native.sh new file mode 100755 index 0000000..ccde0be --- /dev/null +++ b/src/Ultra.Sampler/build_native.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env sh +dotnet publish -c Release -r osx-arm64 +LIB_NAME=libUltraSampler.dylib +LIB_OUTPUT_PATH=./bin/Release/net8.0/osx-arm64/publish/$LIB_NAME +install_name_tool -id $LIB_NAME $LIB_OUTPUT_PATH +cp $LIB_OUTPUT_PATH ./$LIB_NAME +clang -shared -O2 -o libUltraSamplerIndirect.dyld ultra_sampler_indirect.cpp ./$LIB_NAME diff --git a/src/Ultra.Sampler/ultra_sampler_indirect.cpp b/src/Ultra.Sampler/ultra_sampler_indirect.cpp new file mode 100644 index 0000000..8f12523 --- /dev/null +++ b/src/Ultra.Sampler/ultra_sampler_indirect.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include + +extern "C" { + void ultra_sampler_start(); + + + void set_temporary_tmpdir(const char* sub_dir_name, void (*func)()) { + // Get the current TMPDIR + const char* original_tmpdir = getenv("TMPDIR"); + if (!original_tmpdir) { + return; + } + + size_t original_tmpdir_len = strlen(original_tmpdir); + bool has_trailing_slash = original_tmpdir[original_tmpdir_len - 1] == '/'; + + // Construct the new TMPDIR path + size_t new_tmpdir_len = original_tmpdir_len + strlen(sub_dir_name) + 1 + (has_trailing_slash ? 1 : 0); // +1 for '\0', and +1 for the trailing slash + char* new_tmpdir = (char*)malloc(new_tmpdir_len); + if (!new_tmpdir) { + // perror("Failed to allocate memory"); + return; + } + + snprintf(new_tmpdir, new_tmpdir_len, has_trailing_slash ? "%s%s/" : "%s/%s/", original_tmpdir, sub_dir_name); + + // Create the subdirectory if it doesn't exist + if (mkdir(new_tmpdir, 0700) != 0 && errno != EEXIST) { + //perror("Failed to create directory"); + free(new_tmpdir); + return; + } + + // Set the TMPDIR environment variable to the new subdirectory + if (setenv("TMPDIR", new_tmpdir, 1) != 0) { + //perror("Failed to set TMPDIR"); + free(new_tmpdir); + return; + } + free(new_tmpdir); + + pid_t pid = getpid(); + printf("Current Process pid: %d tmpdir: %s\n", pid, getenv("TMPDIR")); + + // Call the arbitrary function + func(); + + // Restore the original TMPDIR + setenv("TMPDIR", original_tmpdir, 1); + } + + __attribute__((visibility("default"),used)) + void ultra_sampler_boot() + { + set_temporary_tmpdir(".ultra", ultra_sampler_start); + } + + __attribute__((visibility("default"),used)) + __attribute__((section("__DATA,__mod_init_func"))) void (*ultra_sampler_boot_ptr)() = &ultra_sampler_boot; +}