19
19
// - go/decommissioning-dbc
20
20
// - go/decommissioning-dbc-engine
21
21
// - go/decommissioning-dbc-tools
22
- #include " flutter/common/settings.h"
23
- #include " flutter/fml/build_config.h" // For OS_IOS.
24
22
25
- #if OS_IOS && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
23
+ #include " flutter/runtime/ptrace_check.h"
24
+
25
+ #if TRACING_CHECKS_NECESSARY
26
26
27
- // These headers should only be needed in debug mode.
28
27
#include < sys/sysctl.h>
29
28
#include < sys/types.h>
30
29
30
+ #include < mutex>
31
+
32
+ #include " flutter/fml/build_config.h"
33
+
34
+ // Being extra careful and adding additional landmines that will prevent
35
+ // compilation of this TU in an incorrect runtime mode.
36
+ static_assert (OS_IOS, " This translation unit is iOS specific." );
37
+ static_assert (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG,
38
+ " This translation unit must only be compiled in the debug "
39
+ " runtime mode as it "
40
+ " contains private API usage." );
41
+
31
42
#define PT_TRACE_ME 0
32
43
#define PT_SIGEXC 12
33
44
extern " C" int ptrace (int request, pid_t pid, caddr_t addr, int data);
34
45
35
- static bool DebuggedIOS (const flutter::Settings& vm_settings) {
46
+ namespace flutter {
47
+
48
+ static bool IsLaunchedByFlutterCLI (const Settings& vm_settings) {
36
49
// Only the Flutter CLI passes "--enable-checked-mode". Therefore, if the flag
37
50
// is present, we have been launched by "ios-deploy" via "debugserver".
38
51
//
39
52
// We choose this flag because it is always passed to launch debug builds.
40
- if (vm_settings.enable_checked_mode ) {
41
- return true ;
42
- }
53
+ return vm_settings.enable_checked_mode ;
54
+ }
43
55
56
+ static bool IsLaunchedByXcode () {
44
57
// Use "sysctl()" to check if we're currently being debugged (e.g. by Xcode).
45
58
// We could also check "getppid() != 1" (launchd), but this is more direct.
46
59
const pid_t self = getpid ();
47
60
int mib[5 ] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, self, 0 };
48
61
49
62
auto proc = std::make_unique<struct kinfo_proc >();
50
63
size_t proc_size = sizeof (struct kinfo_proc );
51
- if (sysctl (mib, 4 , proc.get (), &proc_size, nullptr , 0 ) < 0 ) {
64
+ if (:: sysctl (mib, 4 , proc.get (), &proc_size, nullptr , 0 ) < 0 ) {
52
65
FML_LOG (ERROR) << " Could not execute sysctl() to get current process info: "
53
66
<< strerror (errno);
54
67
return false ;
@@ -57,18 +70,16 @@ static bool DebuggedIOS(const flutter::Settings& vm_settings) {
57
70
return proc->kp_proc .p_flag & P_TRACED;
58
71
}
59
72
60
- void EnsureDebuggedIOS (const flutter::Settings& vm_settings) {
61
- if (DebuggedIOS (vm_settings)) {
62
- return ;
63
- }
64
-
65
- if (ptrace (PT_TRACE_ME, 0 , nullptr , 0 ) == -1 ) {
73
+ static bool EnableTracingManually (const Settings& vm_settings) {
74
+ if (::ptrace (PT_TRACE_ME, 0 , nullptr , 0 ) == -1 ) {
66
75
FML_LOG (ERROR) << " Could not call ptrace(PT_TRACE_ME): " << strerror (errno);
67
76
// No use trying PT_SIGEXC -- it's only needed if PT_TRACE_ME succeeds.
68
- return ;
77
+ return false ;
69
78
}
70
- if (ptrace (PT_SIGEXC, 0 , nullptr , 0 ) == -1 ) {
79
+
80
+ if (::ptrace (PT_SIGEXC, 0 , nullptr , 0 ) == -1 ) {
71
81
FML_LOG (ERROR) << " Could not call ptrace(PT_SIGEXC): " << strerror (errno);
82
+ return false ;
72
83
}
73
84
74
85
// The previous operation causes this process to not be reaped after it
@@ -78,11 +89,12 @@ void EnsureDebuggedIOS(const flutter::Settings& vm_settings) {
78
89
size_t maxproc = 0 ;
79
90
size_t maxproc_size = sizeof (size_t );
80
91
const int sysctl_result =
81
- sysctlbyname (" kern.maxproc" , &maxproc, &maxproc_size, nullptr , 0 );
92
+ :: sysctlbyname (" kern.maxproc" , &maxproc, &maxproc_size, nullptr , 0 );
82
93
if (sysctl_result < 0 ) {
83
94
FML_LOG (ERROR)
84
95
<< " Could not execute sysctl() to determine process count limit: "
85
96
<< strerror (errno);
97
+ return false ;
86
98
}
87
99
88
100
const char * warning =
@@ -98,6 +110,39 @@ void EnsureDebuggedIOS(const flutter::Settings& vm_settings) {
98
110
{
99
111
FML_LOG (ERROR) << warning;
100
112
}
113
+
114
+ return true ;
115
+ }
116
+
117
+ static bool EnableTracingIfNecessaryOnce (const Settings& vm_settings) {
118
+ if (IsLaunchedByFlutterCLI (vm_settings)) {
119
+ return true ;
120
+ }
121
+
122
+ if (IsLaunchedByXcode ()) {
123
+ return true ;
124
+ }
125
+
126
+ return EnableTracingManually (vm_settings);
101
127
}
102
128
103
- #endif // OS_IOS && (FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)
129
+ static TracingResult sTracingResult = TracingResult::kNotAttempted ;
130
+
131
+ bool EnableTracingIfNecessaryImpl (const Settings& vm_settings) {
132
+ static std::once_flag tracing_flag;
133
+
134
+ std::call_once (tracing_flag, [&vm_settings]() {
135
+ sTracingResult = EnableTracingIfNecessaryOnce (vm_settings)
136
+ ? TracingResult::kEnabled
137
+ : TracingResult::kDisabled ;
138
+ });
139
+ return sTracingResult != TracingResult::kDisabled ;
140
+ }
141
+
142
+ TracingResult GetTracingResultImpl () {
143
+ return sTracingResult ;
144
+ }
145
+
146
+ } // namespace flutter
147
+
148
+ #endif // TRACING_CHECKS_NECESSARY
0 commit comments