Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions compat/darwin/procinfo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#include "git-compat-util.h"
#include "strbuf.h"
#include "strvec.h"
#include "trace2.h"
#include <sys/sysctl.h>

/*
* An arbitrarily chosen value to limit the depth of the ancestor chain.
*/
#define NR_PIDS_LIMIT 10

/*
* Get the process name and parent PID for a given PID using sysctl().
* Returns 0 on success, -1 on failure.
*/
static int get_proc_info(pid_t pid, struct strbuf *name, pid_t *ppid)
{
int mib[4];
struct kinfo_proc proc;
size_t size = sizeof(proc);

mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PID;
mib[3] = pid;

if (sysctl(mib, 4, &proc, &size, NULL, 0) < 0)
return -1;

if (size == 0)
return -1;

strbuf_addstr(name, proc.kp_proc.p_comm);
*ppid = proc.kp_eproc.e_ppid;

return 0;
}

/*
* Recursively push process names onto the ancestry array.
* We guard against cycles by limiting the depth to NR_PIDS_LIMIT.
*/
static void push_ancestry_name(struct strvec *names, pid_t pid, int depth)
{
struct strbuf name = STRBUF_INIT;
pid_t ppid;

if (depth >= NR_PIDS_LIMIT)
return;

if (pid <= 0)
return;

if (get_proc_info(pid, &name, &ppid) < 0)
goto cleanup;

strvec_push(names, name.buf);

/*
* Recurse to the parent process. Stop if ppid not valid
* or if we've reached ourselves (cycle).
*/
if (ppid && ppid != pid)
push_ancestry_name(names, ppid, depth + 1);

cleanup:
strbuf_release(&name);
}

void trace2_collect_process_info(enum trace2_process_info_reason reason)
{
struct strvec names = STRVEC_INIT;

if (!trace2_is_enabled())
return;

switch (reason) {
case TRACE2_PROCESS_INFO_STARTUP:
push_ancestry_name(&names, getppid(), 0);
if (names.nr)
trace2_cmd_ancestry(names.v);

strvec_clear(&names);
break;

case TRACE2_PROCESS_INFO_EXIT:
/*
* The Windows version of this calls its
* get_peak_memory_info() here. We may want to insert
* similar process-end statistics here in the future.
*/
break;

default:
BUG("trace2_collect_process_info: unknown reason '%d'", reason);
}
}
2 changes: 2 additions & 0 deletions config.mak.uname
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ ifeq ($(uname_S),Darwin)
HAVE_NS_GET_EXECUTABLE_PATH = YesPlease
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Derrick Stolee wrote on the Git mailing list (how to reply to this email):

On 2/5/2026 11:05 AM, Matthew John Cheetham via GitGitGadget wrote:
>  config.mak.uname                    | 2 ++
>  contrib/buildsystems/CMakeLists.txt | 2 ++
>  meson.build                         | 2 ++

So many build systems!

Each logic you included seems to be correct and matches the patterns from
the Linux case.

Thanks,
-Stolee

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Junio C Hamano wrote on the Git mailing list (how to reply to this email):

"Matthew John Cheetham via GitGitGadget" <gitgitgadget@gmail.com>
writes:

> From: Matthew John Cheetham <mjcheetham@outlook.com>
>
> Include an implementation of trace2_collect_process_info for macOS.
>
> Signed-off-by: Matthew John Cheetham <mjcheetham@outlook.com>
> ---
>  config.mak.uname                    | 2 ++
>  contrib/buildsystems/CMakeLists.txt | 2 ++
>  meson.build                         | 2 ++
>  3 files changed, 6 insertions(+)

Looking good.  I wondered if the first two steps should be a single
patch (as the tree will be with a totally unused file until the
second patch is applied), but this organization will give better
chances for the second patch to be viewed by folks who are good at
build infrastructure who are not necessarily interested in macOS
specific programming, so it probably is better presented this way.

>
> diff --git a/config.mak.uname b/config.mak.uname
> index 1691c6ae6e..baa5018461 100644
> --- a/config.mak.uname
> +++ b/config.mak.uname
> @@ -148,6 +148,8 @@ ifeq ($(uname_S),Darwin)
>  	HAVE_NS_GET_EXECUTABLE_PATH = YesPlease
>  	CSPRNG_METHOD = arc4random
>  	USE_ENHANCED_BASIC_REGULAR_EXPRESSIONS = YesPlease
> +	HAVE_PLATFORM_PROCINFO = YesPlease
> +	COMPAT_OBJS += compat/darwin/procinfo.o
>  
>  	# Workaround for `gettext` being keg-only and not even being linked via
>  	# `brew link --force gettext`, should be obsolete as of
> diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt
> index edb0fc04ad..d489f0cada 100644
> --- a/contrib/buildsystems/CMakeLists.txt
> +++ b/contrib/buildsystems/CMakeLists.txt
> @@ -274,6 +274,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
>  elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
>  	add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
>  	list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)
> +elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
> +	list(APPEND compat_SOURCES compat/darwin/procinfo.c)
>  endif()
>  
>  if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
> diff --git a/meson.build b/meson.build
> index 1f95a06edb..32d470e4f7 100644
> --- a/meson.build
> +++ b/meson.build
> @@ -1292,6 +1292,8 @@ if host_machine.system() == 'linux'
>    libgit_sources += 'compat/linux/procinfo.c'
>  elif host_machine.system() == 'windows'
>    libgit_sources += 'compat/win32/trace2_win32_process_info.c'
> +elif host_machine.system() == 'darwin'
> +  libgit_sources += 'compat/darwin/procinfo.c'
>  else
>    libgit_sources += 'compat/stub/procinfo.c'
>  endif

CSPRNG_METHOD = arc4random
USE_ENHANCED_BASIC_REGULAR_EXPRESSIONS = YesPlease
HAVE_PLATFORM_PROCINFO = YesPlease
COMPAT_OBJS += compat/darwin/procinfo.o

# Workaround for `gettext` being keg-only and not even being linked via
# `brew link --force gettext`, should be obsolete as of
Expand Down
2 changes: 2 additions & 0 deletions contrib/buildsystems/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY )
list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
list(APPEND compat_SOURCES compat/darwin/procinfo.c)
endif()

if(CMAKE_SYSTEM_NAME STREQUAL "Windows")
Expand Down
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,8 @@ if host_machine.system() == 'linux'
libgit_sources += 'compat/linux/procinfo.c'
elif host_machine.system() == 'windows'
libgit_sources += 'compat/win32/trace2_win32_process_info.c'
elif host_machine.system() == 'darwin'
libgit_sources += 'compat/darwin/procinfo.c'
else
libgit_sources += 'compat/stub/procinfo.c'
endif
Expand Down