Catching memory crashes

Questions and Answers about all things *OS (macOS, iOS, tvOS, watchOS)

Catching memory crashes

Postby cahoots » Fri Oct 26, 2018 4:01 pm

Hi, I'm trying to find a good way to catch memory crashes, and the best way I know of (https://code.fb.com/ios/reducing-fooms- ... k-ios-app/) doesn't really do the job. For other crashes, it's easy enough to catch it with signal handlers, but with memory crashes we don't get a signal we can intercept. Is there some crazy way to determine if the app's last session terminated due to a memory crash? I'm most interested in this for iOS, but anything would help.
cahoots
 
Posts: 5
Joined: Mon Oct 08, 2018 3:56 pm

Re: Catching memory crashes

Postby morpheus » Sun Oct 28, 2018 8:36 pm

You actually DO get a signal you can intercept. As explained in detail in Chapter 9. The FB approach in the article isn't the right way to do it, and the article is quite inaccurate . TL;DR: There is more than one way to react to memory pressure, before you get SIGKILLed by jetsam. Rather than explain here, just read the relevant pages:

283.png
283.png (587.85 KiB) Viewed 374 times


284.png
284.png (557.45 KiB) Viewed 374 times


285.png
285.png (586.88 KiB) Viewed 374 times



And mental note to myself: iOS 12 now has /usr/libexec/ReportMemoryException.
morpheus
Site Admin
 
Posts: 704
Joined: Thu Apr 11, 2013 6:24 pm

Re: Catching memory crashes

Postby cahoots » Mon Oct 29, 2018 9:23 pm

Thanks, that makes sense. However, when I try it, kevent returns immediately, adds EV_ERROR to the flags for eventEv, and sets ENOTSUP for the data for eventEv. FYI I'm using an iPhone 8 with iOS 12.0 (16A366). Code:
Code: Select all
    struct kevent changeEv = {0};
    changeEv.filter = EVFILT_VM;
    changeEv.flags = EV_ADD | EV_ENABLE;
    changeEv.fflags = NOTE_VM_PRESSURE_SUDDEN_TERMINATE;
    struct kevent eventEv = {0};
    int n = kevent(kq, &changeEv, 1, &eventEv, 1, NULL);
    assert(n > 0 && !(eventEv.flags & EV_ERROR));
    close(kq);
cahoots
 
Posts: 5
Joined: Mon Oct 08, 2018 3:56 pm

Re: Catching memory crashes

Postby morpheus » Tue Oct 30, 2018 11:19 pm

you're using it wrong; There's an example on how to do the kevent loop in the 1st ed. First set, then read. Also look at XNU's side of things (somewhere in bsd/kern - not near the source right now so can't tell)
morpheus
Site Admin
 
Posts: 704
Joined: Thu Apr 11, 2013 6:24 pm

Re: Catching memory crashes

Postby cahoots » Wed Oct 31, 2018 11:06 pm

Ok, I've tried the example from the first book after replacing the pid with 0, EVFILT_PROC with EVFILT_VM, and NOTE_EXIT | NOTE_FORK | NOTE_EXEC with NOTE_VM_PRESSURE_SUDDEN_TERMINATE. Unfortunately, it still doesn't work, giving ENOTSUP when I run it. Any ideas?

Code: Select all
int main (int argc, char **argv)
{
    pid_t pid; // PID to monitor
    int kq; // The kqueue file descriptor
    int rc; // collecting return values
    int done;
    struct kevent ke;
    pid = atoi(argv[1]);
    kq = kqueue();
    if (kq == -1) { perror("kqueue"); exit(2); }
    // Set process fork/exec notifications
    EV_SET(&ke, 0, EVFILT_VM, EV_ADD,
           NOTE_VM_PRESSURE_SUDDEN_TERMINATE, 0, NULL);
    // Register event
    rc = kevent(kq, &ke, 1, NULL, 0, NULL);
    if (rc < 0) { perror ("kevent"); exit (3); }
    done = 0;
    while (!done) {
        memset(&ke, '\0', sizeof(struct kevent));
        // This blocks until an event matching the filter occurs
        rc = kevent(kq, NULL, 0, &ke, 1, NULL);
        if (rc < 0) { perror ("kevent"); exit (4); }
    } // end while

    NSLog(@"fail");

    return 0;
}
cahoots
 
Posts: 5
Joined: Mon Oct 08, 2018 3:56 pm

Re: Catching memory crashes

Postby cahoots » Tue Nov 06, 2018 11:23 pm

This would be a huge win for iOS developers if it actually works
cahoots
 
Posts: 5
Joined: Mon Oct 08, 2018 3:56 pm


Return to Questions and Answers

Who is online

Users browsing this forum: No registered users and 5 guests