11#include < array>
2+ #include < charconv>
23#include < cctype>
34#include < cerrno>
45#include < cstdarg>
@@ -1040,7 +1041,7 @@ MonodroidRuntime::set_debug_env_vars (void)
10401041#endif /* DEBUG */
10411042
10421043inline void
1043- MonodroidRuntime::set_trace_options (void )
1044+ MonodroidRuntime::set_mono_jit_trace_options (void )
10441045{
10451046 dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN> value;
10461047 if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_TRACE_PROPERTY, value) == 0 )
@@ -1049,6 +1050,108 @@ MonodroidRuntime::set_trace_options (void)
10491050 mono_jit_set_trace_options (value.get ());
10501051}
10511052
1053+ inline void
1054+ MonodroidRuntime::initialize_native_tracing ()
1055+ {
1056+ if (!Logger::native_tracing_enabled ()) [[likely]] {
1057+ return ;
1058+ }
1059+
1060+ dynamic_local_string<PROPERTY_VALUE_BUFFER_LEN> value;
1061+ if (AndroidSystem::monodroid_get_system_property (SharedConstants::DEBUG_MONO_NATIVE_TRACING, value) == 0 || value.empty ()) {
1062+ tracing_auto_start_mode = TracingAutoStartMode::Startup;
1063+ tracing_auto_stop_mode = TracingAutoStopMode::DelayFromStart;
1064+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1065+ return ;
1066+ }
1067+
1068+ constexpr std::string_view param_start_mode_startup { " start-mode=startup" };
1069+ constexpr std::string_view param_start_mode_delay { " start-mode=delay" };
1070+ constexpr std::string_view param_start_mode_justinit { " start-mode=just-init" };
1071+
1072+ constexpr std::string_view param_stop_mode_delay { " stop-mode=delay" };
1073+ constexpr std::string_view param_stop_mode_absolute_delay { " stop-mode=absolute-delay" };
1074+
1075+ constexpr std::string_view param_start_delay { " start-delay=" };
1076+ constexpr std::string_view param_stop_delay { " stop-delay=" };
1077+
1078+ string_segment param;
1079+ while (value.next_token (' ,' , param)) {
1080+ if (param.equal (param_start_mode_startup)) {
1081+ tracing_auto_start_mode = TracingAutoStartMode::Startup;
1082+ continue ;
1083+ }
1084+
1085+ if (param.equal (param_start_mode_delay)) {
1086+ tracing_auto_start_mode = TracingAutoStartMode::Delay;
1087+ tracing_start_delay_ms = TracingConstants::DEFAULT_START_DELAY_MS;
1088+ continue ;
1089+ }
1090+
1091+ if (param.equal (param_start_mode_justinit)) {
1092+ tracing_auto_start_mode = TracingAutoStartMode::JustInit;
1093+ continue ;
1094+ }
1095+
1096+ if (param.equal (param_stop_mode_delay)) {
1097+ tracing_auto_stop_mode = TracingAutoStopMode::DelayFromStart;
1098+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1099+ continue ;
1100+ }
1101+
1102+ if (param.equal (param_stop_mode_absolute_delay)) {
1103+ tracing_auto_stop_mode = TracingAutoStopMode::AbsoluteDelay;
1104+ tracing_stop_delay_ms = TracingConstants::DEFAULT_STOP_DELAY_MS;
1105+ continue ;
1106+ }
1107+
1108+ auto convert_delay = [](string_segment const & s, size_t start, size_t default_value) {
1109+ if (s.length () <= start) {
1110+ log_warn (
1111+ LOG_DEFAULT,
1112+ " Expected value in tracing setting '%s', using the default value of %zums" ,
1113+ s.start (),
1114+ default_value
1115+ );
1116+ return default_value;
1117+ }
1118+
1119+ size_t ret{};
1120+ auto [ptr, errorc] = std::from_chars (s.start () + start, s.start () + s.length (), ret);
1121+ if (errorc == std::errc ()) {
1122+ return ret;
1123+ }
1124+
1125+ if (errorc == std::errc::invalid_argument) {
1126+ log_warn (
1127+ LOG_DEFAULT,
1128+ " Tracing setting value is not a decimal integer: %s. Using the default value of %zums" ,
1129+ s.start (),
1130+ default_value
1131+ );
1132+ } else if (errorc == std::errc::result_out_of_range) {
1133+ log_warn (
1134+ LOG_DEFAULT,
1135+ " Tracing setting value exceeds the maximum allowed one (%zu): %s. Using the default value of %zums" ,
1136+ std::numeric_limits<size_t >::max (),
1137+ s.start (),
1138+ default_value
1139+ );
1140+ }
1141+
1142+ return default_value;
1143+ };
1144+
1145+ if (param.starts_with (param_start_delay)) {
1146+ tracing_start_delay_ms = convert_delay (param, param_start_delay.length () + 1 , TracingConstants::DEFAULT_START_DELAY_MS);
1147+ }
1148+
1149+ if (param.starts_with (param_stop_delay)) {
1150+ tracing_stop_delay_ms = convert_delay (param, param_stop_delay.length () + 1 , TracingConstants::DEFAULT_STOP_DELAY_MS);
1151+ }
1152+ }
1153+ }
1154+
10521155inline void
10531156MonodroidRuntime::set_profile_options ()
10541157{
@@ -1428,6 +1531,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
14281531 mono_trace_set_level_string (mono_log_level.get ());
14291532 }
14301533
1534+ initialize_native_tracing ();
14311535 setup_mono_tracing (mono_log_mask, have_log_assembly, have_log_gc);
14321536 install_logging_handlers ();
14331537
@@ -1442,7 +1546,7 @@ MonodroidRuntime::Java_mono_android_Runtime_initInternal (JNIEnv *env, jclass kl
14421546
14431547 set_profile_options ();
14441548
1445- set_trace_options ();
1549+ set_mono_jit_trace_options ();
14461550
14471551#if defined (DEBUG)
14481552 debug.start_debugging_and_profiling ();
@@ -1615,7 +1719,7 @@ JNICALL Java_mono_android_Runtime_dumpTimingData ([[maybe_unused]] JNIEnv *env,
16151719}
16161720
16171721JNIEXPORT void
1618- JNICALL Java_mono_android_Runtime_dumpTracingData ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass klass)
1722+ JNICALL Java_mono_android_Runtime_stopTracingAndDumpData ([[maybe_unused]] JNIEnv *env, [[maybe_unused]] jclass klass)
16191723{
16201724 // TODO: implement
16211725}
0 commit comments