Process with equal instances but unequal identities

I am looking at some logs that I collected through sysdiagnose and I notice several messages of the form:

...
fault 2025-03-05 01:12:04.034832 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=86764 AUID=502> and <anon<java>(502)(0) pid=86764>
fault 2025-03-05 01:15:05.829696 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88001 AUID=502> and <anon<java>(502)(0) pid=88001>
fault 2025-03-05 01:15:06.047003 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88010 AUID=502> and <anon<java>(502)(0) pid=88010>
fault 2025-03-05 01:15:06.385648 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88012 AUID=502> and <anon<java>(502)(0) pid=88012>
fault 2025-03-05 01:15:07.135896 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88019 AUID=502> and <anon<java>(502)(0) pid=88019>
fault 2025-03-05 01:15:07.491316 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88021 AUID=502> and <anon<java>(502)(0) pid=88021>
fault 2025-03-05 01:15:07.542102 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88022 AUID=502> and <anon<java>(502)(0) pid=88022>
fault 2025-03-05 01:15:07.803126 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88025 AUID=502> and <anon<java>(502)(0) pid=88025>
fault 2025-03-05 01:15:59.774214 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88568 AUID=502> and <anon<java>(502)(0) pid=88568>
fault 2025-03-05 01:16:00.142288 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88572 AUID=502> and <anon<java>(502)(0) pid=88572>
fault 2025-03-05 01:16:00.224019 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88573 AUID=502> and <anon<java>(502)(0) pid=88573>
fault 2025-03-05 01:16:01.180670 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88580 AUID=502> and <anon<java>(502)(0) pid=88580>
fault 2025-03-05 01:16:01.879884 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88588 AUID=502> and <anon<java>(502)(0) pid=88588>
fault 2025-03-05 01:16:02.233165 +0000 runningboardd Two equal instances have unequal identities. <anon<java>(502) pid=88589 AUID=502> and <anon<java>(502)(0) pid=88589>
...

What's strange is that each of the message seems to say that it has identified two instances with unequal identities and yet it prints the same process for each such message. Notice:

fault	2025-03-05 01:16:02.233165 +0000	runningboardd	Two equal instances have unequal identities. <anon<java>(502) pid=88589 AUID=502> and <anon<java>(502)(0) pid=88589>

I suspect the identity it is talking about is the one explained as designated requirement here https://developer.apple.com/documentation/Technotes/tn3127-inside-code-signing-requirements#Designated-requirement. Yet the message isn't clear why the same process would have two different identities. The type of this message is "fault", so I'm guessing that this message is pointing to some genuine issue with the executable of the process. Is that right? Any inputs on what could be wrong here?

This is from a 15.3.1 macosx aarch64 system. On that note, is runningboardd the process which is responsible for these identity checks?

Answered by DTS Engineer in 828608022

IMPORTANT The following contains a lot of implementation details. Don’t encode this knowledge into a product that you ship to a wide range of users. It has changed in the past and will likely change again in the future.

Let’s start with the runningboardd man page. That’s not super helpful, but it does at least tell you that it’s responsible for managing processes. It started on iOS and has since moved to macOS.

Written by jaikiran in 776288021
I suspect the identity it is talking about is the one explained as designated requirement [in TN3127]

That’s not the case. Rather, this is an internal identity used by runningboardd to classify the processes it knows about based on how they got started. For example, an application process has a description that starts with app. You can see these littered throughout the system log:

type: default
time: 13:12:54.328208+0000
process: runningboardd
subsystem: com.apple.runningboard
category: monitor
message: Calculated state for app<application.com.apple.Console.…(502)>…

There are similar prefixes for DEXTs (dext), XPC services (xpcservice), and probably lots of others that I couldn’t find in the logs. However, in your case the prefix is anon, which indicates a process that runningboardd knows about but isn’t managing.

On macOS those are easy to generate. For example, if you build this program and run it from Terminal, it’ll get an anon entry:

import Foundation
func main() {
var auid = au_id_t()
getauid(&auid)
print(getuid(), geteuid(), auid)
let a = ProcessInfo.processInfo.beginActivity(options: [.idleDisplaySleepDisabled], reason: "test")
withExtendedLifetime(a) {
usleep(1_000)
ProcessInfo.processInfo.endActivity(a)
}
}
main()

That’s because starting the .idleDisplaySleepDisabled activity has to raise an assertion [1] with runningboardd, which causes the process to check in with it, whereupon it realises that it doesn’t know anything about this process and allocates it an identity. In the system log you see this:

type: default
time: 13:46:06.946686+0000
process: runningboardd
subsystem: com.apple.runningboard
category: process
message: Resolved pid 35518 to [anon<Test776288>(502):35518]

So, let’s look at the two identities for your process, reformatted so that the columns line up:

<anon<java>(502) pid=88589 AUID=502>
<anon<java>(502)(0) pid=88589 >

These are obviously the same process, pid 88589, but some details differ. That’s what this log entry is complaining about.

As to how your process got two identities, I’m not 100% sure. The AUID refers to the audit user ID, that is, the value returned by getauid. I wasn’t able to determine what the (0) means.

I suspect that this is due to the weird way that Java apps launch themselves, often involving things like a fork without an exec, or vice versa. However, I played around with various techniques like that and wasn’t able to reproduce it.

I’m inclined to investigate this further, because it’s a sign that Java is straying off the beaten path, and such excursion tend to eventually result in weird issues.

Are you able to reproduce this reliably? If so, it’d be helpful if you could try to isolate what about the Java startup sequence is triggering it.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] I’m using assertion in the context defined in UIApplication Background Task Notes.

IMPORTANT The following contains a lot of implementation details. Don’t encode this knowledge into a product that you ship to a wide range of users. It has changed in the past and will likely change again in the future.

Let’s start with the runningboardd man page. That’s not super helpful, but it does at least tell you that it’s responsible for managing processes. It started on iOS and has since moved to macOS.

Written by jaikiran in 776288021
I suspect the identity it is talking about is the one explained as designated requirement [in TN3127]

That’s not the case. Rather, this is an internal identity used by runningboardd to classify the processes it knows about based on how they got started. For example, an application process has a description that starts with app. You can see these littered throughout the system log:

type: default
time: 13:12:54.328208+0000
process: runningboardd
subsystem: com.apple.runningboard
category: monitor
message: Calculated state for app<application.com.apple.Console.…(502)>…

There are similar prefixes for DEXTs (dext), XPC services (xpcservice), and probably lots of others that I couldn’t find in the logs. However, in your case the prefix is anon, which indicates a process that runningboardd knows about but isn’t managing.

On macOS those are easy to generate. For example, if you build this program and run it from Terminal, it’ll get an anon entry:

import Foundation
func main() {
var auid = au_id_t()
getauid(&auid)
print(getuid(), geteuid(), auid)
let a = ProcessInfo.processInfo.beginActivity(options: [.idleDisplaySleepDisabled], reason: "test")
withExtendedLifetime(a) {
usleep(1_000)
ProcessInfo.processInfo.endActivity(a)
}
}
main()

That’s because starting the .idleDisplaySleepDisabled activity has to raise an assertion [1] with runningboardd, which causes the process to check in with it, whereupon it realises that it doesn’t know anything about this process and allocates it an identity. In the system log you see this:

type: default
time: 13:46:06.946686+0000
process: runningboardd
subsystem: com.apple.runningboard
category: process
message: Resolved pid 35518 to [anon<Test776288>(502):35518]

So, let’s look at the two identities for your process, reformatted so that the columns line up:

<anon<java>(502) pid=88589 AUID=502>
<anon<java>(502)(0) pid=88589 >

These are obviously the same process, pid 88589, but some details differ. That’s what this log entry is complaining about.

As to how your process got two identities, I’m not 100% sure. The AUID refers to the audit user ID, that is, the value returned by getauid. I wasn’t able to determine what the (0) means.

I suspect that this is due to the weird way that Java apps launch themselves, often involving things like a fork without an exec, or vice versa. However, I played around with various techniques like that and wasn’t able to reproduce it.

I’m inclined to investigate this further, because it’s a sign that Java is straying off the beaten path, and such excursion tend to eventually result in weird issues.

Are you able to reproduce this reliably? If so, it’d be helpful if you could try to isolate what about the Java startup sequence is triggering it.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] I’m using assertion in the context defined in UIApplication Background Task Notes.

Hello Quinn,

IMPORTANT The following contains a lot of implementation details. Don’t encode this knowledge into a product that you ship to a wide range of users. It has changed in the past and will likely change again in the future.

I understand.

I suspect the identity it is talking about is the one explained as designated requirement [in TN3127]

That’s not the case. Rather, this is an internal identity used by runningboardd to classify the processes it knows about based on how they got started.

Thank you for clarifying that.

That’s because starting the .idleDisplaySleepDisabled activity has to raise an assertion [1] with runningboardd, which causes the process to check in with it,

Would you happen to know what activities (or system calls or library functions?) would make a java process raise an assertion with runningboardd?

As to how your process got two identities, I’m not 100% sure. The AUID refers to the audit user ID, that is, the value returned by getauid. I wasn’t able to determine what the (0) means.

I suspect that this is due to the weird way that Java apps launch themselves, often involving things like a fork without an exec, or vice versa. However, I played around with various techniques like that and wasn’t able to reproduce it.

Indeed, there are several ways to launch a Java program but most of times the entry happens through the java executable. Java standard APIs also has a java.lang.ProcessBuilder class which allows for a running Java program to launch any other process (and that launched process can be itself be a Java program) https://docs.oracle.com/en/java/javase/23/docs/api/java.base/java/lang/ProcessBuilder.html#start(). On macos platform, ProcessBuilder.start() ends up calling posix_spawn system call to launch the new process.

I will take a deeper look today/tomorrow to see if I can reproduce these logs on my local setup with some experimental java applications.

Written by DTS Engineer in 828608022
I wasn’t able to determine what the (0) means.

I asked about that internally and we suspect that it’s caused by one of these internal identities being cloned with an override of the audit user ID being set to 0. However, I’m able to take this further at this time. The runningboardd implementation is complex and to learn more I’d need to consult with the folks who maintain that, and I don’t want to do that until I know more about your side of this equation.

Written by jaikiran in 828636022
Would you happen to know what activities … would make a java process raise an assertion with runningboardd?

All sorts of things. In my test I was using a ProcessInfo activity because that’s simplest thing I could think of. However, there are many different types of assertions and many APIs that raise them. They are usually associated with GUI frameworks, but not always, as my ProcessInfo example shows.

Written by jaikiran in 828636022
I will take a deeper look today/tomorrow to see if I can reproduce these logs on my local setup with some experimental java applications.

Cool.

Some suggestions on that front:

  • You might wanna try a GUI app in Java. Our GUI frameworks are the most common source of these assertions.

  • Java apps on the Mac often have a main executable that’s a script, which then invokes Java. That’s a common source of grief, as I explain in the TCC and Main Executables section of On File System Permissions.

However, this is all just speculation.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I asked about that internally and we suspect that it’s caused by one of these internal identities being cloned with an override of the audit user ID being set to 0. However, I’m able to take this further at this time. The runningboardd implementation is complex and to learn more I’d need to consult with the folks who maintain that, and I don’t want to do that until I know more about your side of this equation.

Thank you Quinn for looking deeper into this. I have been trying to reproduce this locally but so far I haven't been able to. This is still on my TODO list to investigate and I hope to get back shortly with additional details when I have them.

Just to clear, the presence of this log message does indicate that there is some genuine issue that is worth investigating, right?

Written by jaikiran in 829065022
the presence of this log message does indicate that there is some genuine issue that is worth investigating, right?

I don’t know )-:

I think it’s worrying enough that it warrants investigation. Once we understand how it’s happening, that’ll offer more insight into whether:

  • It’s something you should fix.

  • It’s triggered by some weird configuration set up by folks using your runtime, in which case it’s really on them.

  • It’s log noise that you can file a bug about.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Understood, thank you. I'll try to find a way to reproduce this on a system where I have local control.

Process with equal instances but unequal identities
 
 
Q