Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c14b3ef
[NativeAOT] Add printf-style native logging
simonrozsival Jul 16, 2026
90e6fb6
[native] Test printf-style logging
simonrozsival Jul 17, 2026
2cb0c4e
[Tests] Follow Android string helper convention
simonrozsival Jul 17, 2026
4a27f68
[Tests] Import Android string helpers
simonrozsival Jul 17, 2026
ee07100
[Tests] Remove native logging test harness
simonrozsival Jul 17, 2026
c907892
[NativeAOT] Migrate runtime utility logging to printf
simonrozsival Jul 17, 2026
7a34259
[CoreCLR/NativeAOT] Migrate configuration diagnostics to printf
simonrozsival Jul 17, 2026
a1bf4b7
Address printf logging review feedback
simonrozsival Jul 17, 2026
2e31630
Merge updated printf logging base
simonrozsival Jul 17, 2026
3b8673f
Merge updated printf logging base
simonrozsival Jul 17, 2026
09f0690
Support printf logging helpers on MonoVM
simonrozsival Jul 17, 2026
66d731d
Merge MonoVM printf logging support
simonrozsival Jul 17, 2026
88ca523
Merge MonoVM printf logging support
simonrozsival Jul 17, 2026
72cad5d
Use printf configuration logging on MonoVM
simonrozsival Jul 17, 2026
00aa7d4
Centralize native printf logging declarations
jonathanpeppers Jul 20, 2026
fcd87d4
Reuse NativeAOT bridge status strings
jonathanpeppers Jul 20, 2026
1c244d8
Merge main into native printf logging
jonathanpeppers Jul 20, 2026
71cfe50
Use canonical printf logging declarations
jonathanpeppers Jul 20, 2026
f28e855
Preserve mmap diagnostic alignment
jonathanpeppers Jul 21, 2026
b8f2e27
Merge PR 12155 for stacked review
jonathanpeppers Jul 21, 2026
23fa284
Merge branch 'main' into dev/simonrozsival/nativeaot-runtime-printf-l…
jonathanpeppers Jul 21, 2026
d11efec
Update CoreCLR APK size reference
jonathanpeppers Jul 22, 2026
fce7aeb
Merge branch 'main' into dev/simonrozsival/nativeaot-runtime-printf-l…
jonathanpeppers Jul 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"Size": 6652
},
"classes.dex": {
"Size": 9413828
"Size": 9413840
},
"classes2.dex": {
"Size": 157836
"Size": 158304
},
"kotlin/annotation/annotation.kotlin_builtins": {
"Size": 928
Expand All @@ -32,31 +32,31 @@
"Size": 2396
},
"lib/arm64-v8a/libassembly-store.so": {
"Size": 11696200
"Size": 11900968
},
"lib/arm64-v8a/libclrjit.so": {
"Size": 2757816
"Size": 2761136
},
"lib/arm64-v8a/libcoreclr.so": {
"Size": 4837240
"Size": 4839560
},
"lib/arm64-v8a/libmonodroid.so": {
"Size": 1252416
"Size": 1188568
},
Comment on lines 43 to 45

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, great the changes here reduced the size of libmonodroid.so.

"lib/arm64-v8a/libSystem.Globalization.Native.so": {
"Size": 72112
"Size": 72432
},
"lib/arm64-v8a/libSystem.IO.Compression.Native.so": {
"Size": 1258776
},
"lib/arm64-v8a/libSystem.Native.so": {
"Size": 99664
"Size": 99776
},
"lib/arm64-v8a/libSystem.Security.Cryptography.Native.Android.so": {
"Size": 163936
"Size": 169768
},
"lib/arm64-v8a/libxamarin-app.so": {
"Size": 159496
"Size": 156056
},
"META-INF/androidx.activity_activity.version": {
"Size": 6
Expand Down Expand Up @@ -2234,5 +2234,5 @@
"Size": 794696
}
},
"PackageSize": 20782669
}
"PackageSize": 20971085
}
4 changes: 2 additions & 2 deletions src/native/clr/host/host-shared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ auto HostCommon::get_java_class_name_for_TypeManager (jclass klass) noexcept ->
JNIEnv *env = OSBridge::ensure_jnienv ();
jstring name = reinterpret_cast<jstring> (env->CallObjectMethod (klass, Class_getName));
if (name == nullptr) {
log_error (LOG_DEFAULT, "Failed to obtain Java class name for object at {:p}", reinterpret_cast<void*>(klass));
log_errorf (LOG_DEFAULT, "Failed to obtain Java class name for object at %p", reinterpret_cast<void*>(klass));
return nullptr;
}

const char *mutf8 = env->GetStringUTFChars (name, nullptr);
if (mutf8 == nullptr) {
log_error (LOG_DEFAULT, "Failed to convert Java class name to UTF8 (out of memory?)"sv);
log_errorf (LOG_DEFAULT, "Failed to convert Java class name to UTF8 (out of memory?)");
env->DeleteLocalRef (name);
return nullptr;
}
Expand Down
59 changes: 42 additions & 17 deletions src/native/clr/include/runtime-base/util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ namespace xamarin::android {
{
struct stat sbuf;
if (fstatat (dirfd, file_name, &sbuf, 0) == -1) {
log_warn (LOG_ASSEMBLY, "Failed to stat file '{}': {}", file_name, std::strerror (errno));
log_warnf (LOG_ASSEMBLY, "Failed to stat file '%s': %s", optional_string (file_name), std::strerror (errno));
return std::nullopt;
}

Expand All @@ -154,18 +154,30 @@ namespace xamarin::android {
[[gnu::flatten, gnu::always_inline]]
static void set_environment_variable (const char *name, const char *value) noexcept
{
log_debug (LOG_DEFAULT, "Setting environment variable {} = '{}'", optional_string (name), optional_string (value));
log_debugf (LOG_DEFAULT, "Setting environment variable %s = '%s'", optional_string (name), optional_string (value));
if (::setenv (name, value, 1) < 0) {
log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
log_warnf (LOG_DEFAULT, "Failed to set environment variable '%s': %s", optional_string (name), ::strerror (errno));
}
}

[[gnu::flatten, gnu::always_inline]]
static void set_environment_variable_if_unset (std::string_view const& name, jstring_wrapper& value) noexcept
{
log_debug (LOG_DEFAULT, "Setting environment variable {} = '{}' if unset", name, value.get_string_view ());
log_debugf (
LOG_DEFAULT,
"Setting environment variable %.*s = '%s' if unset",
static_cast<int>(name.length ()),
name.data (),
optional_string (value.get_cstr ())
);
if (::setenv (name.data (), value.get_cstr (), 0) < 0) {
log_warn (LOG_DEFAULT, "Failed to set environment variable '{}': {}", name, ::strerror (errno));
log_warnf (
LOG_DEFAULT,
"Failed to set environment variable '%.*s': %s",
static_cast<int>(name.length ()),
name.data (),
::strerror (errno)
);
}
}

Expand All @@ -187,7 +199,14 @@ namespace xamarin::android {
if (createDirectory) {
int rv = create_directory (value.get_cstr (), mode);
if (rv < 0 && errno != EEXIST) {
log_warn (LOG_DEFAULT, "Failed to create directory '{}' for environment variable '{}'. {}", value.get_string_view (), name, strerror (errno));
log_warnf (
LOG_DEFAULT,
"Failed to create directory '%s' for environment variable '%.*s'. %s",
optional_string (value.get_cstr ()),
static_cast<int>(name.length ()),
name.data (),
strerror (errno)
);
}
}
set_environment_variable (name, value);
Expand Down Expand Up @@ -217,32 +236,33 @@ namespace xamarin::android {
mmap_info.area = mmap (nullptr, offsetSize, PROT_READ, MAP_PRIVATE, fd, static_cast<off_t>(offsetPage));

if (mmap_info.area == MAP_FAILED) {
Helpers::abort_application (
Helpers::abort_applicationf (
LOG_ASSEMBLY,
std::format (
"Could not mmap APK fd {}: {}; File={}",
fd,
strerror (errno),
filename
)
std::source_location::current (),
"Could not mmap APK fd %d: %s; File=%.*s",
fd,
strerror (errno),
static_cast<int>(filename.length ()),
filename.data ()
);
}

mmap_info.size = offsetSize;
file_info.area = pointer_add (mmap_info.area, offsetFromPage);
file_info.size = size;

log_info (
log_infof (
LOG_ASSEMBLY,
" mmap_start: {:<8p}; mmap_end: {:<8p} mmap_len: {:<12} file_start: {:<8p} file_end: {:<8p} file_len: {:<12} apk descriptor: {} file: {}",
" mmap_start: %-8p; mmap_end: %-8p\t mmap_len: %-12zu file_start: %-8p file_end: %-8p\t file_len: %-12zu\t apk descriptor: %d file: %.*s",
mmap_info.area,
pointer_add (mmap_info.area, mmap_info.size),
mmap_info.size,
file_info.area,
pointer_add (file_info.area, file_info.size),
file_info.size,
fd,
filename
static_cast<int>(filename.length ()),
filename.data ()
);

return file_info;
Expand All @@ -265,7 +285,12 @@ namespace xamarin::android {
elf_header->e_ident[EI_MAG1] != ELFMAG1 ||
elf_header->e_ident[EI_MAG2] != ELFMAG2 ||
elf_header->e_ident[EI_MAG3] != ELFMAG3) {
log_debug (LOG_ASSEMBLY, "Not an ELF image: {}", file_name);
log_debugf (
LOG_ASSEMBLY,
"Not an ELF image: %.*s",
static_cast<int>(file_name.length ()),
file_name.data ()
);
// Not an ELF image, just return what we mmapped before
return { map_info.area, map_info.size };
}
Expand Down
12 changes: 9 additions & 3 deletions src/native/clr/runtime-base/android-system-shared.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ AndroidSystem::monodroid__system_property_get (std::string_view const& name, cha
char *buf = nullptr;
if (sp_value_len < Constants::PROPERTY_VALUE_BUFFER_LEN) {
size_t alloc_size = Helpers::add_with_overflow_check<size_t> (Constants::PROPERTY_VALUE_BUFFER_LEN, 1uz);
log_warn (LOG_DEFAULT, "Buffer to store system property may be too small, will copy only {} bytes", sp_value_len);
log_warnf (LOG_DEFAULT, "Buffer to store system property may be too small, will copy only %zu bytes", sp_value_len);
buf = new char [alloc_size];
}

Expand Down Expand Up @@ -81,10 +81,16 @@ AndroidSystem::get_max_gref_count_from_system () noexcept -> long
}

if (*e) {
log_warn (LOG_GC, "Unsupported '{}' value '{}'.", Constants::DEBUG_MONO_MAX_GREFC.data (), override.get ());
log_warnf (
LOG_GC,
"Unsupported '%.*s' value '%s'.",
static_cast<int>(Constants::DEBUG_MONO_MAX_GREFC.length ()),
Constants::DEBUG_MONO_MAX_GREFC.data (),
override.get ()
);
}

log_warn (LOG_GC, "Overriding max JNI Global Reference count to {}", max);
log_warnf (LOG_GC, "Overriding max JNI Global Reference count to %ld", max);
}

return max;
Expand Down
26 changes: 22 additions & 4 deletions src/native/clr/runtime-base/util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,13 @@ Util::create_public_directory (std::string_view const& dir)
// Try to change the mode, just in case
chmod (dir.data (), 0777);
} else {
log_warn (LOG_DEFAULT, "Failed to create directory '{}'. {}"sv, dir, std::strerror (errno));
log_warnf (
LOG_DEFAULT,
"Failed to create directory '%.*s'. %s",
static_cast<int>(dir.length ()),
dir.data (),
std::strerror (errno)
);
}
}
umask (m);
Expand All @@ -72,7 +78,13 @@ Util::monodroid_fopen (std::string_view const& filename, std::string_view const&
*/
FILE *ret = fopen (filename.data (), mode.data ());
if (ret == nullptr) {
log_error (LOG_DEFAULT, "fopen failed for file {}: {}", filename, strerror (errno));
log_errorf (
LOG_DEFAULT,
"fopen failed for file %.*s: %s",
static_cast<int>(filename.length ()),
filename.data (),
strerror (errno)
);
return nullptr;
}

Expand All @@ -87,7 +99,13 @@ void Util::set_world_accessable (std::string_view const& path)
} while (r == -1 && errno == EINTR);

if (r == -1) {
log_error (LOG_DEFAULT, "chmod(\"{}\", 0664) failed: {}", path, strerror (errno));
log_errorf (
LOG_DEFAULT,
"chmod(\"%.*s\", 0664) failed: %s",
static_cast<int>(path.length ()),
path.data (),
strerror (errno)
);
}
}

Expand All @@ -99,7 +117,7 @@ auto Util::set_world_accessible (int fd) noexcept -> bool
} while (r == -1 && errno == EINTR);

if (r == -1) {
log_error (LOG_DEFAULT, "fchmod() failed: {}"sv, strerror (errno));
log_errorf (LOG_DEFAULT, "fchmod() failed: %s", strerror (errno));
return false;
}

Expand Down
Loading