FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer

Time to time I see the error 'FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer' if CGImageForProposedRect is called immediately after start: https://developer.apple.com/documentation/appkit/nsimage/1519861-cgimageforproposedrect

_RegisterApplication(), FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer, err=-50

This error appears only one time during start. What does this error mean?

Thank you in advance!

Answered by DTS Engineer in 798309022

First, as a broad answer, you should take a look at "On Log Noise", as this log message is a reasonable good example of the genre. Your app may have some role in the issue, but I wouldn't consider the problem all that critical unless you're having some other issues.

Getting into the specifics, reordered a bit for clarity:

Time to time I see the error 'FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer'

_RegisterApplication(), FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer, err=-50

What does this error mean?

When initially launched "an app" isn't really any different than any other process. It's created by launchd, then "starts running code" just like any other process. However, (typically) very early in it's launch process, it establishes a series of connections with a number of daemon's in the system, which make it "an app". "_RegisterApplication()" is one of the very early functions that initiates that process. More specifically, "_RegisterApplication()" connects your app into the ProcessManager* and then tries to connect you to the WindowServer.

*Yes, the Carbon ProcessManager still sort of exists.

The historically minded might notice that "-50" is the mac classic error code "paramErr" and that the name "_RegisterApplication()" is not exactly inline with our more modern naming conventions. While the implementation details have changed over time, the general code "flow" and frameworks involved here are very, very, very old. Much of the original implementation of this "check" process was originally written as the C layer underneath Carbon and Cocoa.

WHY exactly you failed is not a question I can really answer, as "paramErr" is the default error of the underlying function that's actually failing. You can check the console log for any additional info (look for logging from the "WindowServer" process and any message that reference "Skylight") and please post it back here if you find anything interesting.

In any case, in theory you'd think this error would be catastrophic. The connection to the WindowServer is one of the critical connections that makes your app "an app", since the WindowServer is how your app both receives input events from the system AND is able to draw out to the screen. No window server connection means you're not really "an app". However, in practice, that's not really what happens. All of this infrastructure is so critical that there are multiple connection paths so that a "failure" at one point generally ends up being hidden/covered up by a later success. All of this is also happening VERY early in your apps lifetime (for example, your app isn't visible on the screen at all), so unless the failure is permanent you're unlikely to "know" anything when wrong.

Case in point:

This error appears only one time during start.

If the problem persisted, your app wouldn't work at all.

if CGImageForProposedRect is called immediately after start

How "immediately" do you mean? If this is happening after one of the early delegate methods (say, "applicationDidFinishLaunching"), then that's deeply weird and potentially worrying. If it's happening before "applicationDidFinishLaunching", then my advice would be to avoid calling into our graphics frameworks before your app has initialized.

Also, how exactly are you running your app? Launching your app by running your app "directly" for example, by executing it's binary through terminal instead of having the system launch it, can sometimes trigger this sort of error/logging. Bypassing LaunchServices means you've (technically) violated the API contract but our frameworks tend to "self correct", so your app ends up working anyway.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Accepted Answer

First, as a broad answer, you should take a look at "On Log Noise", as this log message is a reasonable good example of the genre. Your app may have some role in the issue, but I wouldn't consider the problem all that critical unless you're having some other issues.

Getting into the specifics, reordered a bit for clarity:

Time to time I see the error 'FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer'

_RegisterApplication(), FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer, err=-50

What does this error mean?

When initially launched "an app" isn't really any different than any other process. It's created by launchd, then "starts running code" just like any other process. However, (typically) very early in it's launch process, it establishes a series of connections with a number of daemon's in the system, which make it "an app". "_RegisterApplication()" is one of the very early functions that initiates that process. More specifically, "_RegisterApplication()" connects your app into the ProcessManager* and then tries to connect you to the WindowServer.

*Yes, the Carbon ProcessManager still sort of exists.

The historically minded might notice that "-50" is the mac classic error code "paramErr" and that the name "_RegisterApplication()" is not exactly inline with our more modern naming conventions. While the implementation details have changed over time, the general code "flow" and frameworks involved here are very, very, very old. Much of the original implementation of this "check" process was originally written as the C layer underneath Carbon and Cocoa.

WHY exactly you failed is not a question I can really answer, as "paramErr" is the default error of the underlying function that's actually failing. You can check the console log for any additional info (look for logging from the "WindowServer" process and any message that reference "Skylight") and please post it back here if you find anything interesting.

In any case, in theory you'd think this error would be catastrophic. The connection to the WindowServer is one of the critical connections that makes your app "an app", since the WindowServer is how your app both receives input events from the system AND is able to draw out to the screen. No window server connection means you're not really "an app". However, in practice, that's not really what happens. All of this infrastructure is so critical that there are multiple connection paths so that a "failure" at one point generally ends up being hidden/covered up by a later success. All of this is also happening VERY early in your apps lifetime (for example, your app isn't visible on the screen at all), so unless the failure is permanent you're unlikely to "know" anything when wrong.

Case in point:

This error appears only one time during start.

If the problem persisted, your app wouldn't work at all.

if CGImageForProposedRect is called immediately after start

How "immediately" do you mean? If this is happening after one of the early delegate methods (say, "applicationDidFinishLaunching"), then that's deeply weird and potentially worrying. If it's happening before "applicationDidFinishLaunching", then my advice would be to avoid calling into our graphics frameworks before your app has initialized.

Also, how exactly are you running your app? Launching your app by running your app "directly" for example, by executing it's binary through terminal instead of having the system launch it, can sometimes trigger this sort of error/logging. Bypassing LaunchServices means you've (technically) violated the API contract but our frameworks tend to "self correct", so your app ends up working anyway.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

First off all thank you a lot for your response and help.

How "immediately" do you mean?

This happens VERY early in apps lifetime. Process starts separate thread which triggers CGImageForProposedRect.

How exactly are you running your app?

Looks like this happens only under debugger which launches app "directly" (executing it's binary). This process is planned to run as launch agent (app bundle).

I am afraid I can not check the fact of finishing app launching because app does not rely on NSApplication(https://developer.apple.com/documentation/appkit/nsrunningapplication/1532002-finishedlaunching?language=objc)

Are there any other way to check the application is established all necessary connections with system daemons?

Nothing interesting in console log was found.

Thank you!

I am afraid I can not check the fact of finishing app launching because app does not rely on NSApplication(https://developer.apple.com/documentation/appkit/nsrunningapplication/1532002-finishedlaunching?language=objc) Are there any other way to check the application is established all necessary connections with system daemons?

Let me reverse that question as ask what you ARE doing. What does your component actually "do"? You said it's a launch agent, but will it present any kind of UI or is it intended to be completely invisible to the user? What's running your main thread? Do you have any kind of event loop?

First off all thank you a lot for your response and help.

How "immediately" do you mean?

This happens VERY early in apps lifetime. Process starts separate thread which triggers CGImageForProposedRect.

Starts it where/how? The biggest issue here is activity that's initiated at library load time, which means it "starts" before main() actually begins executing. That's something I would STRENOUSLY avoid, as your basically assuming that all of our framework will do the "right" thing, even though you don't yet have an operational main thread.

How exactly are you running your app?

Looks like this happens only under debugger which launches app "directly" (executing it's binary). This process is planned to run as launch agent (app bundle).

Having said all that, if this truly ONLY happens in the debugger, then I'm not sure I'd be all that concerned about it, assuming the only issues is the log messages itself. Particularly when you're not building off our standard architecture (which it sounds like you're not), the debugger can create odd scenarios that would otherwise just not occur. This is even more true if you're running the debugger "directly" instead of through Xcode.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thank you for the help!

You said it's a launch agent, but will it present any kind of UI or is it intended to be completely invisible to the user?

There is no any UI implementation. This is background process.

What does your component actually "do"?

The call CGImageForProposedRect is triggered by NSWorkspaceDidActivateApplicationNotification event. NSWorkspaceDidActivateApplicationNotification handler is triggered if IDE(not Xcode) gets focus immediately after starting app under debugger.

Looks like DidActivateApplicationNotification is received before application is launched. Is it expected behavior?

What does your component actually "do"? The call CGImageForProposedRect is triggered by NSWorkspaceDidActivateApplicationNotification event. NSWorkspaceDidActivateApplicationNotification handler is triggered if IDE(not Xcode) gets focus immediately after starting app under debugger.

I think I need to get a much better understanding of how you're code works before I can really help you here. What's running on your main thread? What are you actually trying to do and how/why are you trying to do it?

My concern here is that you're basically pulling bits of the system together in a way that manages to be somewhat functional, but doesn't actually "work" in the larger sense. FYI, based on what you've said so far, I would probably build this around the standard AppKit template, then used LSUIElement to hide/remove myself from the normal interface. This has a few advantages:

  1. You can use the standard lifecycle architecture instead of trying to figure out/fix it yourself.

  2. Related to that point, it lets you avoid trying to figure out what you "should" do when running your own runloop.

  3. For development purposes, you can use LSUIElement to make your "app" visible again, which is often useful when you're testing things.

Just to be clear about this:

You said it's a launch agent, but will it present any kind of UI or is it intended to be completely invisible to the user? There is no any UI implementation. This is background process.

The fact you aren't going to have any UI doesn't mean you can't/shouldn't use NSApplication. Using NSApplication means that you can connect yourself into the same broad architecture the system uses to manage "applications". That can be very useful, even if nothing you do is ever visible to the user.

Looks like DidActivateApplicationNotification is received before application is launched. Is it expected behavior?

Expected by who? This is an example of why I STRONGLY recommend just using NSApplication directly- the question you should be asking here isn't "Why did NSWorkspaceDidActivateApplicationNotification occur early?", it's "Why did NSWorkspaceDidActivateApplicationNotification occur at all?" To put that another way, why are you relying on application level notifications when you don't use NSApplication?

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Hello Kevin,

The most part of application is written on C++ due to a lot of cross platform code. The entry point is main() where CFRunLoopRun() is called.

AppKit framework is called by C++ via wrapper class around an Objective-C (pimpl idiom). The goal is to get icon of app which is currently active.

Looks like the only correct way to approach the problem is to start the main event loop via NSApplication.

I did the following modifications:

  1. Replaced the call CFRunLoopRun() to [[NSApplication sharedApplication] run] in main().
  2. Added check [[NSRunningApplication currentApplication] isFinishedLaunching].

Looks like this solution works.

Thank you a lot for your help and time! I learned a lot of valuable things.

The second solution is to move all initialisation from main() to class which implements the protocol NSApplicationDelegate into the method applicationDidFinishLaunching. I suppose this solution is recommended.

Thank you again!

The most part of application is written on C++ due to a lot of cross platform code. The entry point is main() where CFRunLoopRun() is called. AppKit framework is called by C++ via wrapper class around an Objective-C (pimpl idiom). The goal is to get icon of app which is currently active.

OK, I suspected something like that but it's good to have confirmation.

Looks like the only correct way to approach the problem is to start the main event loop via NSApplication.

Yes, that's what I would do.

More specifically, unless doing something very limited, it often works better to construct a background (meaning it has no interface at all) agent as "an app the the user can't see or interact with" instead of as a "bare run loop that only executes very specific things".

At a technical level, you can actually make either approach work. However, NSApplication gives you:

  1. An established and documented architecture you can build off of.

  2. Fits your process into the standard system architecture for "free" (for example, supporting things like 'quit' events).

  3. Is generally less "expensive" than you'd think (memory, performance, complexity, etc.).

In many case, that last point is often the most critical. It's easy to assume that the app architecture is inherently a lot "heavier" but that's not really the case, at least not entirely. Case in point, here:

The second solution is to move all initialisation from main() to class which implements the protocol NSApplicationDelegate into the method applicationDidFinishLaunching. I suppose this solution is recommended.

Yes. More specifically, if you start with our simplest app template in ObjectiveC then:

-Add the key "LSUIElement = YES" in your Info.plist. This prevents the app from appearing in the dock/app switcher/etc.

-In the app delegate, delete the window property:

@property (strong) IBOutlet NSWindow *window;

-In the xib file delete the window object.

That gives you a fully "functioning" app that simply doesn't have any "interface" when it's launched. Your code would then "kick off" in applicationDidFinishLaunching.

I did the following modifications: Replaced the call CFRunLoopRun() to [[NSApplication sharedApplication] run] in main(). Added check [[NSRunningApplication currentApplication] isFinishedLaunching]. Looks like

this solution works.

The NSApplication class reference actually summarizes what NSApplicationMain does as:

void NSApplicationMain(int argc, char *argv[]) {
    [NSApplication sharedApplication];
    [NSBundle loadNibNamed:@"myMain" owner:NSApp];
    [NSApp run];
}

That summary is in fact quite accurate. The main difference in the "real" implementation is a lot more error checking, getting the values to load from the Info.plist, and dealing with things like storyboard vs. nib loading. Your code is doing the same thing, except using NSApplicationMain means you're building directly on our implementation instead of working off of a rough copy.


Kevin Elliott
DTS Engineer, CoreOS/Hardware

thank you for the help!

FAILED TO REGISTER PROCESS WITH CPS/CoreGraphics in WindowServer
 
 
Q