Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

jmagman
Copy link
Member

@jmagman jmagman commented Nov 7, 2020

Description

The ptrace trick may not be necessary on iOS 14.2 (beta release candidate) which seems to have added JIT compilation support. This means Flutter debug apps aren't sigkilled when launched without an attached debugger.

There's speculation that this is only true on A12 (and presumably later A-) chips. With #define TRACING_CHECKS_NECESSARY 0 a debug app launched from the home screen on my A12 iPad Pro, but on @xster's A9 iPhone 6s it still crashed.

#define TRACING_CHECKS_NECESSARY \
OS_IOS && !TARGET_OS_SIMULATOR && \
(FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG)

The outstanding theory is JIT may only be working on arm64e devices running iOS 14.2.

Related Issues

Fixes flutter/flutter#69984

Testing

I have no idea how to test this any more than the rest of this ptrace file without adding some wrappers around sysctlbyname. Unfortunately I don't think we have any arm64e devicelab test devices, either.

@jmagman jmagman self-assigned this Nov 7, 2020
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@jmagman
Copy link
Member Author

jmagman commented Nov 7, 2020

Let's hold off actually merging this until we know more about what devices still need tracing, but I wanted a PR ready to go.

int major_version = 0;
char minor_letter = 'Z';

for (size_t index = 0; index < osversion_size; index++) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This parsing felt like an interview question (atoi!), happy to try something more idiomatic if ya'll can think of a better way to do it. I started with an istringstream but it actually wound up being identical logic so it didn't seem worth the extra object.

return false;
}

// Check for iOS 14.2 and higher.
Copy link
Member

Choose a reason for hiding this comment

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

up to you but it feels like we're building in a lot of platform specific knowledge at this point. How about just letting this file statically take a SetOSVersionMayNeedTracingCheck injection or something and FlutterEngine can just set it to https://developer.apple.com/documentation/foundation/nsprocessinfo/1414876-isoperatingsystematleastversion? Could save us some work.

Copy link
Member Author

@jmagman jmagman Nov 9, 2020

Choose a reason for hiding this comment

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

If this were all in obj-c++ world then I wouldn't have bothered with all these syctl checks. But it would need to be injected from:

const bool tracing_result = EnableTracingIfNecessary(settings_);

Copy link
Member

Choose a reason for hiding this comment

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

that's what I meant injecting it statically (since all these stuff is static anyway). Since the engine calls first, we know it would be set before dart calls it again.

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't love that the lower level code would require a static variable to be set before it can be called, without enforcing that ordering itself. Seems like an easy opportunity for bugs if this ever gets refactored. Will defer to @chinmaygarde's opinion here.

If we decide to keep this kern.osversion parsing I'll add a unit test.

Copy link
Member

Choose a reason for hiding this comment

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

I love the initiative in doing this in C, but let's make this an ObjC++ TU and use NSOperatingSystemVersion instead. You can remove the TRACING_CHECKS_NECESSARY macro and add a stub C++ file for non-Darwin platforms.


// Tracing is necessary unless the device is arm64e (A12 chip or higher).
if (cputype != CPU_TYPE_ARM64 || cpusubtype != CPU_SUBTYPE_ARM64E) {
return false;
Copy link
Member

Choose a reason for hiding this comment

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

ultra-nit: there's a triple negation at this point :) false to != arm64 to unnecessary. Can we simplify slightly?

@@ -27,6 +27,7 @@
#include <sys/sysctl.h>
#include <sys/types.h>

#include <mach/machine.h>
Copy link
Member

Choose a reason for hiding this comment

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

Should this be conditionally imported and used? @chinmaygarde might have a better idea of whether this is available on all our target platforms.

Copy link
Member

Choose a reason for hiding this comment

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

This is fine. TRACING_CHECKS_NECESSARY is unset on all other platforms.

Copy link
Member

@chinmaygarde chinmaygarde left a comment

Choose a reason for hiding this comment

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

Construction issues aside, this must not land as you'd still to check if the entitlement is present at the specific iOS version. Apps without the entitlement in debug will still crash. I'd also rather link to Apple's documentation instead of relying on speculation right now.

@@ -27,6 +27,7 @@
#include <sys/sysctl.h>
#include <sys/types.h>

#include <mach/machine.h>
Copy link
Member

Choose a reason for hiding this comment

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

This is fine. TRACING_CHECKS_NECESSARY is unset on all other platforms.

cpu_type_t cputype = 0;
size_t cputype_size = sizeof(cpu_type_t);
if (::sysctlbyname("hw.cputype", &cputype, &cputype_size, nullptr, 0) < 0) {
FML_LOG(ERROR) << "Could not execute sysctl() to get CPU type: "
Copy link
Member

Choose a reason for hiding this comment

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

Here and elsewhere: Early return in case of error.

return false;
}

// Check for iOS 14.2 and higher.
Copy link
Member

Choose a reason for hiding this comment

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

I love the initiative in doing this in C, but let's make this an ObjC++ TU and use NSOperatingSystemVersion instead. You can remove the TRACING_CHECKS_NECESSARY macro and add a stub C++ file for non-Darwin platforms.


// Check for iOS 14.2 and higher.
size_t osversion_size;
::sysctlbyname("kern.osversion", NULL, &osversion_size, NULL, 0);
Copy link
Member

Choose a reason for hiding this comment

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

Unchecked error code. Though, I'd suggest using the ObjC++ variant instead.

@chinmaygarde
Copy link
Member

@jmagman Any updates? Have you tried this without the entitlement in the plist?

@jmagman
Copy link
Member Author

jmagman commented Nov 12, 2020

@jmagman Any updates?

I haven't created the ObjC++ variant yet. On this PR it's working on an (arm64e) iPad Pro by launching without the debugger attached and running the app. And on an (arm64) iPhone 6s it's showing the warning screen.

Have you tried this without the entitlement in the plist?
you'd still to check if the entitlement is present at the specific iOS version.

Which entitlement? get-task-allow?

I'd also rather link to Apple's documentation instead of relying on speculation right now.

Yeah all I have is speculation about the A12 and higher chips.

@jmagman jmagman added the Work in progress (WIP) Not ready (yet) for review! label Nov 18, 2020
@jmagman
Copy link
Member Author

jmagman commented Dec 15, 2020

@zanderso Would you like me to keep working on this so users can launch apps from the home screen on new devices? Or should I abandon?

@zanderso
Copy link
Member

I think we should probably abandon until we can get some more solid info about the devices where this is supported.

@jmagman jmagman closed this Dec 15, 2020
@jmagman jmagman deleted the ptrace_14-2 branch December 15, 2020 20:23
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Always launch in JIT mode on iOS 14.2 even when debugger isn't attached (remove ptrace check)
4 participants