Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions src/native/clr/include/shared/log_types.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <cstdarg>
#include <cstdint>
#include <format>
#include <string>
Expand Down Expand Up @@ -47,6 +48,12 @@ namespace xamarin::android {
// A slightly faster alternative to other log functions as it doesn't parse the message
// for format placeholders nor it uses variable arguments
void log_write (LogCategories category, LogLevel level, const char *message) noexcept;
void log_writev (LogCategories category, LogLevel level, const char *format, va_list args) noexcept;
void log_writef (LogCategories category, LogLevel level, const char *format, ...) noexcept __attribute__ ((format (printf, 3, 4)));
void log_debugf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_infof (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_warnf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_errorf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));

[[gnu::always_inline]]
static inline void log_write (LogCategories category, LogLevel level, std::string_view const& message) noexcept
Expand Down
21 changes: 18 additions & 3 deletions src/native/clr/shared/helpers.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <cstdarg>
#include <cstdio>
#include <cstring>
#include <android/set_abort_message.h>

Expand All @@ -7,11 +8,24 @@

using namespace xamarin::android;

[[noreturn]] void
Helpers::abort_applicationf (LogCategories category, std::source_location sloc, const char *format, ...) noexcept
{
char *message = nullptr;
const char *safe_format = format == nullptr ? "<null>" : format;
va_list args;
va_start (args, format);
int ret = vasprintf (&message, safe_format, args);
va_end (args);

abort_application (category, ret < 0 ? safe_format : message, true, sloc);
}

[[noreturn]] void
Helpers::abort_application (LogCategories category, const char *message, bool log_location, std::source_location sloc) noexcept
{
// Log it, but also...
log_fatal (category, "{}", message);
log_write (category, LogLevel::Fatal, message);

// ...let android include it in the tombstone, debuggerd output, stack trace etc
android_set_abort_message (message);
Expand All @@ -33,9 +47,10 @@ Helpers::abort_application (LogCategories category, const char *message, bool lo
}
}

log_fatal (
log_writef (
category,
"Abort at {}:{}:{} ('{}')",
LogLevel::Fatal,
"Abort at %s:%u:%u ('%s')",
file_name,
sloc.line (),
sloc.column (),
Expand Down
77 changes: 70 additions & 7 deletions src/native/clr/shared/log_functions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,17 @@ namespace {
};

constexpr size_t loglevel_map_max_index = (sizeof(loglevel_map) / sizeof(android_LogPriority)) - 1;

[[gnu::always_inline]]
auto priority_for_level (LogLevel level) noexcept -> android_LogPriority
{
size_t map_index = static_cast<size_t>(level);
if (map_index > loglevel_map_max_index) {
return DEFAULT_PRIORITY;
}

return loglevel_map[map_index];
}
}

unsigned int log_categories = LOG_NONE;
Expand Down Expand Up @@ -117,15 +128,67 @@ namespace xamarin::android {
void
log_write (LogCategories category, LogLevel level, const char *message) noexcept
{
size_t map_index = static_cast<size_t>(level);
android_LogPriority priority;
__android_log_write (priority_for_level (level), category_name (category), message);
}

if (map_index > loglevel_map_max_index) {
priority = DEFAULT_PRIORITY;
} else {
priority = loglevel_map[map_index];
void
log_writev (LogCategories category, LogLevel level, const char *format, va_list args) noexcept
{
const char *safe_format = format == nullptr ? "<null>" : format;
__android_log_vprint (priority_for_level (level), category_name (category), safe_format, args);
}

void
log_writef (LogCategories category, LogLevel level, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, level, format, args);
va_end (args);
}

void
log_debugf (LogCategories category, const char *format, ...) noexcept
{
if ((log_categories & category) == 0) {
return;
}

va_list args;
va_start (args, format);
log_writev (category, LogLevel::Debug, format, args);
va_end (args);
}

void
log_infof (LogCategories category, const char *format, ...) noexcept
{
if ((log_categories & category) == 0) {
return;
}

__android_log_write (priority, category_name (category), message);
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Info, format, args);
va_end (args);
}

void
log_warnf (LogCategories category, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Warn, format, args);
va_end (args);
}

void
log_errorf (LogCategories category, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Error, format, args);
va_end (args);
}

}
12 changes: 6 additions & 6 deletions src/native/common/include/runtime-base/timing-internal.hh
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ namespace xamarin::android {
// likely we'll run out of memory way, way, way before that happens
size_t old_size = events.capacity ();
events.reserve (old_size << 1);
log_warn (LOG_TIMING, "Reallocated timing event buffer from {} to {}"sv, old_size, events.size ());
log_warnf (LOG_TIMING, "Reallocated timing event buffer from %zu to %zu", old_size, events.capacity ());
}
}

Expand Down Expand Up @@ -378,7 +378,7 @@ namespace xamarin::android {
{
struct timespec t;
if (clock_gettime (CLOCK_MONOTONIC_RAW, &t) != 0) [[unlikely]] {
log_warn (LOG_TIMING, "clock_gettime failed for CLOCK_MONOTONIC_RAW: {}"sv, optional_string (strerror (errno)));
log_warnf (LOG_TIMING, "clock_gettime failed for CLOCK_MONOTONIC_RAW: %s", optional_string (strerror (errno)));
return {}; // Results will be nonsensical, but no point in aborting the app
}
return time_point (chrono::seconds (t.tv_sec) + chrono::nanoseconds (t.tv_nsec));
Expand Down Expand Up @@ -494,10 +494,10 @@ namespace xamarin::android {
return;
}

log_warn (
log_warnf (
LOG_TIMING,
"Unknown event kind '{}' logged"sv,
static_cast<std::underlying_type_t<decltype(kind)>>(kind)
"Unknown event kind '%u' logged",
static_cast<unsigned int>(kind)
);
append_desc ("unknown event kind"sv);
}
Expand All @@ -510,7 +510,7 @@ namespace xamarin::android {
auto is_valid_event_index (size_t index, std::source_location sloc = std::source_location::current ()) const noexcept -> bool
{
if (index >= events.capacity ()) [[unlikely]] {
log_warn (LOG_TIMING, "Invalid event index passed to method '{}'"sv, sloc.function_name ());
log_warnf (LOG_TIMING, "Invalid event index passed to method '%s'", optional_string (sloc.function_name ()));
return false;
}

Expand Down
16 changes: 8 additions & 8 deletions src/native/common/include/runtime-base/timing.hh
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ namespace xamarin::android

using namespace std::literals;
auto interval = seq->end - seq->start; // nanoseconds
auto text = std::format (
"{}; elapsed: {}:{}::{}"sv,
message == nullptr ? ""sv : message,
static_cast<uint64_t>((std::chrono::duration_cast<std::chrono::seconds>(interval).count ())),
static_cast<uint64_t>((std::chrono::duration_cast<std::chrono::milliseconds>(interval)).count ()),
static_cast<uint64_t>((interval % 1ms).count ())
log_writef (
LOG_TIMING,
level,
"%s; elapsed: %llu:%llu::%llu",
optional_string (message, ""),
static_cast<unsigned long long>(std::chrono::duration_cast<std::chrono::seconds>(interval).count ()),
static_cast<unsigned long long>(std::chrono::duration_cast<std::chrono::milliseconds>(interval).count ()),
static_cast<unsigned long long>((interval % 1ms).count ())
);

log_write (LOG_TIMING, level, text.c_str ());
}

private:
Expand Down
3 changes: 3 additions & 0 deletions src/native/common/include/shared/helpers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ namespace xamarin::android
[[noreturn]]
static void abort_application (LogCategories category, const char *message, bool log_location = true, std::source_location sloc = std::source_location::current ()) noexcept;

[[noreturn]]
static void abort_applicationf (LogCategories category, std::source_location sloc, const char *format, ...) noexcept __attribute__ ((format (printf, 3, 4)));

[[noreturn]]
static void abort_application (LogCategories category, std::string const& message, bool log_location = true, std::source_location sloc = std::source_location::current ()) noexcept
{
Expand Down
77 changes: 70 additions & 7 deletions src/native/mono/shared/log_functions.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <array>
#include <cstdarg>
#include <strings.h>

#include <android/log.h>
Expand Down Expand Up @@ -102,19 +103,81 @@ static constexpr android_LogPriority loglevel_map[] = {

static constexpr size_t loglevel_map_max_index = (sizeof(loglevel_map) / sizeof(android_LogPriority)) - 1;

static auto
priority_for_level (xamarin::android::LogLevel level) noexcept -> android_LogPriority
{
size_t map_index = static_cast<size_t>(level);
if (map_index > loglevel_map_max_index) {
return DEFAULT_PRIORITY;
}

return loglevel_map[map_index];
}

namespace xamarin::android {
void
log_write (LogCategories category, LogLevel level, const char *message) noexcept
{
size_t map_index = static_cast<size_t>(level);
android_LogPriority priority;
__android_log_write (priority_for_level (level), CATEGORY_NAME (category), message);
}

void
log_writev (LogCategories category, LogLevel level, const char *format, va_list args) noexcept
{
const char *safe_format = format == nullptr ? "<null>" : format;
__android_log_vprint (priority_for_level (level), CATEGORY_NAME (category), safe_format, args);
}

void
log_writef (LogCategories category, LogLevel level, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, level, format, args);
va_end (args);
}

void
log_debugf (LogCategories category, const char *format, ...) noexcept
{
if ((log_categories & category) == 0) {
return;
}

va_list args;
va_start (args, format);
log_writev (category, LogLevel::Debug, format, args);
va_end (args);
}

if (map_index > loglevel_map_max_index) {
priority = DEFAULT_PRIORITY;
} else {
priority = loglevel_map[map_index];
void
log_infof (LogCategories category, const char *format, ...) noexcept
{
if ((log_categories & category) == 0) {
return;
}

__android_log_write (priority, CATEGORY_NAME (category), message);
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Info, format, args);
va_end (args);
}

void
log_warnf (LogCategories category, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Warn, format, args);
va_end (args);
}

void
log_errorf (LogCategories category, const char *format, ...) noexcept
{
va_list args;
va_start (args, format);
log_writev (category, LogLevel::Error, format, args);
va_end (args);
}
}
7 changes: 7 additions & 0 deletions src/native/mono/shared/log_types.hh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <cstdarg>
#include <cstdint>
#include <format>
#include <string>
Expand Down Expand Up @@ -47,6 +48,12 @@ namespace xamarin::android {
// A slightly faster alternative to other log functions as it doesn't parse the message
// for format placeholders nor it uses variable arguments
void log_write (LogCategories category, LogLevel level, const char *message) noexcept;
void log_writev (LogCategories category, LogLevel level, const char *format, va_list args) noexcept;
void log_writef (LogCategories category, LogLevel level, const char *format, ...) noexcept __attribute__ ((format (printf, 3, 4)));
void log_debugf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_infof (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_warnf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));
void log_errorf (LogCategories category, const char *format, ...) noexcept __attribute__ ((format (printf, 2, 3)));

[[gnu::always_inline]]
static inline void log_write (LogCategories category, LogLevel level, std::string_view const& message) noexcept
Expand Down
16 changes: 5 additions & 11 deletions src/native/nativeaot/host/bridge-processing.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#include <format>

#include <host/bridge-processing.hh>
#include <runtime-base/logger.hh>
#include <shared/helpers.hh>
Expand All @@ -21,16 +19,12 @@ void BridgeProcessing::naot_initialize_on_runtime_init (JNIEnv *env) noexcept
GCUserPeerable_jiClearManagedReferences = env->GetMethodID (GCUserPeerable_class, "jiClearManagedReferences", "()V");

if (GCUserPeerable_jiAddManagedReference == nullptr || GCUserPeerable_jiClearManagedReferences == nullptr) [[unlikely]] {
constexpr auto ABSENT = "absent"sv;
constexpr auto PRESENT = "present"sv;

Helpers::abort_application (
Helpers::abort_applicationf (
LOG_DEFAULT,
std::format (
"Failed to find GCUserPeerable method(s): jiAddManagedReference ({}); jiClearManagedReferences ({})"sv,
GCUserPeerable_jiAddManagedReference == nullptr ? ABSENT : PRESENT,
GCUserPeerable_jiClearManagedReferences == nullptr ? ABSENT : PRESENT
)
std::source_location::current (),
"Failed to find GCUserPeerable method(s): jiAddManagedReference (%s); jiClearManagedReferences (%s)",
GCUserPeerable_jiAddManagedReference == nullptr ? "absent" : "present",
GCUserPeerable_jiClearManagedReferences == nullptr ? "absent" : "present"
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/native/nativeaot/host/host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ auto HostCommon::Java_JNI_OnLoad (JavaVM *vm, void *reserved) noexcept -> jint

if (__jni_on_load_handler_count > 0) {
for (uint32_t i = 0; i < __jni_on_load_handler_count; i++) {
log_debug (
log_debugf (
LOG_ASSEMBLY,
"Calling JNI on-load init func '{}' ({:p})",
"Calling JNI on-load init func '%s' (%p)",
optional_string (__jni_on_load_handler_names[i]),
reinterpret_cast<void*>(__jni_on_load_handlers[i])
);
Expand Down
Loading