Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exit code detection failing on iOS/tvOS 15+ #819

Closed
Tracked by #9136
premun opened this issue Feb 9, 2022 · 6 comments · Fixed by #847
Closed
Tracked by #9136

Exit code detection failing on iOS/tvOS 15+ #819

premun opened this issue Feb 9, 2022 · 6 comments · Fixed by #847
Assignees
Labels
apple iOS/tvOS/WatchOS/Mac Catalyst area bug critical emulator Related to an emulator/Simulator

Comments

@premun
Copy link
Member

premun commented Feb 9, 2022

With the latest move of dotnet/runtime onto OSX 12.00, apple run and apple just-run commands started failing in 100% of cases:

image

Metrics
| where EventType == "_MobileDeviceOperation" and MetricName == "ExitCode"
| join kind=inner Jobs on JobId
| where Finished > now()-1d
| extend Dimensions = parse_json(Dimensions)
| project 
    Finished,
    JobName,
    QueueName,
    WorkItemFriendlyName,
    Platform = tostring(Dimensions.platform),
    Command = tostring(Dimensions.command),
    ExitCode = MetricValue,
    Target = tostring(Dimensions.target),
    IsDevice = tobool(Dimensions.isDevice)
| where Platform == "apple"
| summarize SuccessRate=countif(ExitCode < 6)*100/count(), Count=count() by Platform, Command, QueueName
| where SuccessRate != 100
| order by Platform, SuccessRate, Command
@premun premun self-assigned this Feb 9, 2022
@premun premun added apple iOS/tvOS/WatchOS/Mac Catalyst area bug critical emulator Related to an emulator/Simulator labels Feb 9, 2022
@premun
Copy link
Member Author

premun commented Mar 2, 2022

Seems like the issue is Xcode 13.2 rather than OSX 12.00.

Also I found out, I might be able to use kqueue and kevent to get notified about a process' exit where the exit code should be in the data of the event:
https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/kevent.2.html

EVFILT_PROC  Takes the process ID to monitor as the	identifier and
			 the events to watch for in fflags, and	returns	when
			 the process performs one or more of the requested
			 events.  If a process can normally see	another
			 process, it can attach	an event to it.	 The events to
			 monitor are:

			 NOTE_EXIT	   The process has exited. The exit status will be stored in data.

@premun
Copy link
Member Author

premun commented Mar 2, 2022

Oh noez, the sentence "The exit status will be stored in data." actually only appears in FreeBSD man pages and not OSX man pages 😢

I have tested getting the PID (the line with kev.data):

// cc test.c -framework CoreFoundation -O

#include <CoreFoundation/CoreFoundation.h>
#include <unistd.h>
#include <sys/event.h>

// build: cc test.c -framework CoreFoundation -O
// run: ./a.out 57168

static void noteProcDeath(CFFileDescriptorRef fdref, CFOptionFlags callBackTypes, void *info) {
    struct kevent kev;
    int fd = CFFileDescriptorGetNativeDescriptor(fdref);
    kevent(fd, NULL, 0, &kev, 1, NULL);
    // take action on death of process here
    printf("process with pid '%u' died with '%ld'\n", (unsigned int)kev.ident, kev.data);
    CFFileDescriptorInvalidate(fdref);
    CFRelease(fdref); // the CFFileDescriptorRef is no longer of any use in this example
}

// one argument, an integer pid to watch, required
int main(int argc, char *argv[]) {
    if (argc < 2) exit(1);
    int fd = kqueue();
    struct kevent kev;
    EV_SET(&kev, atoi(argv[1]), EVFILT_PROC, EV_ADD|EV_ENABLE, NOTE_EXIT, 0, NULL);
    kevent(fd, &kev, 1, NULL, 0, NULL);
    CFFileDescriptorRef fdref = CFFileDescriptorCreate(kCFAllocatorDefault, fd, true, noteProcDeath, NULL);
    CFFileDescriptorEnableCallBacks(fdref, kCFFileDescriptorReadCallBack);
    CFRunLoopSourceRef source = CFFileDescriptorCreateRunLoopSource(kCFAllocatorDefault, fdref, 0);
    CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopDefaultMode);
    CFRelease(source);
    // run the run loop for 20 seconds
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 200.0, false);
    return 0;
}

It is always 0 😢

This also supports that: https://lists.apple.com/archives/Darwin-dev/2009/Aug/msg00210.html

@premun
Copy link
Member Author

premun commented Mar 3, 2022

This is not a problem of Xcode, this is a problem of iOS 15. The system log of the simulator contains a very limited amount of logs compared to 13.5 for example (both running on Xcode 13.1).

@premun premun changed the title Exit code detection failing on OSX 12.00 Exit code detection failing on iOS/tvOS 15+ Mar 3, 2022
@premun
Copy link
Member Author

premun commented Mar 3, 2022

I was able to get more logs via:

xcrun simctl spawn booted log stream --level=Info | grep [APP NAME]

The exit code is there, so is the stdout. So we should also be able to fix #694

More info:
https://stackoverflow.com/questions/10165641/how-can-i-get-the-console-logs-from-the-ios-simulator

@premun
Copy link
Member Author

premun commented Mar 18, 2022

Solution for Simulators is here: https://github.com/premun/xharness/tree/prvysoky/simulator-exit-code

MacCatalyst is left

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
apple iOS/tvOS/WatchOS/Mac Catalyst area bug critical emulator Related to an emulator/Simulator
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant