11#include < array>
2+ #include < charconv>
23#include < cctype>
34#include < cerrno>
45#include < cstdarg>
@@ -1057,7 +1058,7 @@ MonodroidRuntime::set_debug_env_vars (void)
10571058#endif /* DEBUG */
10581059
10591060inline void
1060- MonodroidRuntime::set_trace_options (void )
1061+ MonodroidRuntime::set_mono_jit_trace_options (void )
10611062{
10621063 dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN> value;
10631064 if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_TRACE_PROPERTY, value) == 0 )
@@ -1066,6 +1067,108 @@ MonodroidRuntime::set_trace_options (void)
10661067 mono_jit_set_trace_options (value.get ());
10671068}
10681069
1070+ inline void
1071+ MonodroidRuntime::initialize_native_tracing ()
1072+ {
1073+ if (!Logger::native_tracing_enabled ()) [[likely]] {
1074+ return ;
1075+ }
1076+
1077+ dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN> value;
1078+ if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_NATIVE_TRACING, value) == 0 || value.empty ()) {
1079+ tracing_auto_start_mode = TracingAutoStartMode::Startup;
1080+ tracing_auto_stop_mode = TracingAutoStopMode::DelayFromStart;
1081+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1082+ return ;
1083+ }
1084+
1085+ constexpr std::string_view param_start_mode_startup { " start-mode=startup" };
1086+ constexpr std::string_view param_start_mode_delay { " start-mode=delay" };
1087+ constexpr std::string_view param_start_mode_justinit { " start-mode=just-init" };
1088+
1089+ constexpr std::string_view param_stop_mode_delay { " stop-mode=delay" };
1090+ constexpr std::string_view param_stop_mode_absolute_delay { " stop-mode=absolute-delay" };
1091+
1092+ constexpr std::string_view param_start_delay { " start-delay=" };
1093+ constexpr std::string_view param_stop_delay { " stop-delay=" };
1094+
1095+ string_segment param;
1096+ while (value.next_token (' ,' , param)) {
1097+ if (param.equal (param_start_mode_startup)) {
1098+ tracing_auto_start_mode = TracingAutoStartMode::Startup;
1099+ continue ;
1100+ }
1101+
1102+ if (param.equal (param_start_mode_delay)) {
1103+ tracing_auto_start_mode = TracingAutoStartMode::Delay;
1104+ tracing_start_delay_ms = TracingConstants::DEFAULT_START_DELAY_MS;
1105+ continue ;
1106+ }
1107+
1108+ if (param.equal (param_start_mode_justinit)) {
1109+ tracing_auto_start_mode = TracingAutoStartMode::JustInit;
1110+ continue ;
1111+ }
1112+
1113+ if (param.equal (param_stop_mode_delay)) {
1114+ tracing_auto_stop_mode = TracingAutoStopMode::DelayFromStart;
1115+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1116+ continue ;
1117+ }
1118+
1119+ if (param.equal (param_stop_mode_absolute_delay)) {
1120+ tracing_auto_stop_mode = TracingAutoStopMode::AbsoluteDelay;
1121+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1122+ continue ;
1123+ }
1124+
1125+ auto convert_delay = [](string_segment const & s, size_t start, size_t default_value) {
1126+ if (s.length () <= start) {
1127+ log_warn (
1128+ LOG_DEFAULT,
1129+ " Expected value in tracing setting '%s', using the default value of %zums" ,
1130+ s.start (),
1131+ default_value
1132+ );
1133+ return default_value;
1134+ }
1135+
1136+ size_t ret{};
1137+ auto [ptr, errorc] = std::from_chars (s.start () + start, s.start () + s.length (), ret);
1138+ if (errorc == std::errc ()) {
1139+ return ret;
1140+ }
1141+
1142+ if (errorc == std::errc::invalid_argument) {
1143+ log_warn (
1144+ LOG_DEFAULT,
1145+ " Tracing setting value is not a decimal integer: %s. Using the default value of %zums" ,
1146+ s.start (),
1147+ default_value
1148+ );
1149+ } else if (errorc == std::errc::result_out_of_range) {
1150+ log_warn (
1151+ LOG_DEFAULT,
1152+ " Tracing setting value exceeds the maximum allowed one (%zu): %s. Using the default value of %zums" ,
1153+ std::numeric_limits<size_t >::max (),
1154+ s.start (),
1155+ default_value
1156+ );
1157+ }
1158+
1159+ return default_value;
1160+ };
1161+
1162+ if (param.starts_with (param_start_delay)) {
1163+ tracing_start_delay_ms = convert_delay (param, param_start_delay.length () + 1 , TracingConstants::DEFAULT_START_DELAY_MS);
1164+ }
1165+
1166+ if (param.starts_with (param_stop_delay)) {
1167+ tracing_stop_delay_ms = convert_delay (param, param_stop_delay.length () + 1 , TracingConstants::DEFAULT_STOP_DELAY_MS);
1168+ }
1169+ }
1170+ }
1171+
10691172inline void
10701173MonodroidRuntime::set_profile_options ()
10711174{
@@ -1446,6 +1549,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
14461549 mono_trace_set_level_string (mono_log_level.get ());
14471550 }
14481551
1552+ initialize_native_tracing ();
14491553 setup_mono_tracing (mono_log_mask, have_log_assembly, have_log_gc);
14501554 install_logging_handlers ();
14511555
@@ -1460,7 +1564,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
14601564
14611565 set_profile_options ();
14621566
1463- set_trace_options ();
1567+ set_mono_jit_trace_options ();
14641568
14651569#if defined (DEBUG)
14661570 debug.start_debugging_and_profiling ();
@@ -1635,7 +1739,7 @@ JNICALL Java_mono_android_Runtime_dumpTimingData ([[maybe_unused]] JNIEnv *env,
16351739}
16361740
16371741JNIEXPORT void
1638- JNICALL Java_mono_android_Runtime_dumpTracingData ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass klass)
1742+ JNICALL Java_mono_android_Runtime_stopTracingAndDumpData ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass klass)
16391743{
16401744 // TODO: implement
16411745}
0 commit comments