func getProcArgs()

in metric/system/process/process_darwin.go [172:247]


func getProcArgs(pid int, filter func(string) bool) ([]string, string, mapstr.M, error) {
	mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)}
	argmax := uintptr(C.ARG_MAX)
	buf := make([]byte, argmax)
	err := sysctl(mib, &buf[0], &argmax, nil, 0)
	if err != nil {
		return nil, "", nil, fmt.Errorf("error in sysctl: %w", err)
	}

	bbuf := bytes.NewBuffer(buf)
	bbuf.Truncate(int(argmax))

	var argc int32                                    // raw buffer
	_ = binary.Read(bbuf, binary.LittleEndian, &argc) // read length

	path, err := bbuf.ReadBytes(0)
	if err != nil {
		return nil, "", nil, fmt.Errorf("error reading the executable name: %w", err)
	}

	exeName := stripNullByte(path)

	// skip trailing nul bytes
	for {
		c, err := bbuf.ReadByte()
		if err != nil {
			return nil, "", nil, fmt.Errorf("error skipping nul values in KERN_PROCARGS2 buffer: %w", err)
		}
		if c != 0 {
			_ = bbuf.UnreadByte()
			break
		}
	}

	// read CLI args
	argv := make([]string, 0, argc)
	for i := 0; i < int(argc); i++ {
		arg, err := bbuf.ReadBytes(0)
		if err == io.EOF {
			break
		}
		if err != nil {
			return nil, exeName, nil, fmt.Errorf("error reading args from KERN_PROCARGS2: %w", err)
		}
		argv = append(argv, stripNullByte(arg))
	}

	delim := []byte{61} // "=" for key value pairs

	envVars := mapstr.M{}
	var envErr error
	for {
		line, err := bbuf.ReadBytes(0)
		if err == io.EOF || line[0] == 0 {
			break
		}
		if err != nil {
			return argv, exeName, nil, fmt.Errorf("error reading args from KERN_PROCARGS2 buffer: %w", err)
		}
		pair := bytes.SplitN(stripNullByteRaw(line), delim, 2)

		if len(pair) != 2 {
			// invalid k-v pair encountered, return non-fatal error so that we can continue
			err := fmt.Errorf("error reading process information from KERN_PROCARGS2: encountered invalid env pair for pid %d", pid)
			envErr = errors.Join(envErr, NonFatalErr{Err: err})
			continue
		}
		eKey := string(pair[0])
		if filter == nil || filter(eKey) {
			envVars[string(pair[0])] = string(pair[1])
		}

	}

	return argv, exeName, envVars, envErr
}