How to call an equivalent command to strace on mac -- ideally from python?
Asked Answered
H

6

8

Self contained reproducible example

I need to strace the output of any command through python. But I only need to translate the following amd linux command to mac m1/arm commands (so python is likely irrelevant):

strace -e trace=execve -v -s 100000000 -xx -ttt -ff -o output.txt sh -c 'echo hi'

How do I do that?

This fails for me:

 ❯ sudo dtruss -t execve -f sh -c 'echo hi'
dtrace: system integrity protection is on, some features will not be available

dtrace: failed to execute sh: Operation not permitted

Note:

  • I have complete control of the input so I can do sudo and related commands in my mac (it's mainly to debug my code, so it works on pycharm)

Strace from brew fails

I can't seem to install strace from brew:

 ❯ brew install strace
Running `brew update --auto-update`...
strace: Linux is required for this software.
[email protected]: Linux is required for this software.
Error: strace: Unsatisfied requirements failed this build.

Execsnoop also failed

❯ sudo execsnoop sh -c 'echo hi'

dtrace: system integrity protection is on, some features will not be available

dtrace: invalid probe specifier 
 /*
  * Command line arguments
  */
 inline int OPT_dump    = 0;
 inline int OPT_cmd     = 0;
 inline int OPT_time    = 0;
 inline int OPT_timestr = 0;
 inline int OPT_zone    = 0;
 inline int OPT_safe    = 0;
 inline int OPT_proj    = 0;
 inline int FILTER      = 0;
 inline string COMMAND  = ".";
 
 #pragma D option quiet
 #pragma D option switchrate=10hz
 
 /*
  * Print header
  */
 dtrace:::BEGIN 
 {
        /* print optional headers */
        OPT_time    ? printf("%-14s ", "TIME") : 1;
        OPT_timestr ? printf("%-20s ", "STRTIME") : 1;
        OPT_zone    ? printf("%-10s ", "ZONE") : 1;
        OPT_proj    ? printf("%5s ", "PROJ") : 1;

        /* print main headers */
        /* APPLE: Removed "ZONE" header, it has no meaning in darwin */
        OPT_dump    ? printf("%s %s %s %s %s %s %s\n",
            "TIME", "PROJ", "UID", "PID", "PPID", "COMM", "ARGS") :
            printf("%5s %6s %6s %s\n", "UID", "PID", "PPID", "ARGS");
 }

 /*
  * Print exec event
  */
 /* SOLARIS: syscall::exec:return, syscall::exece:return */
proc:::exec-success
 /(FILTER == 0) || (OPT_cmd == 1 && COMMAND == strstr(COMMAND, execname)) || (OPT_cmd == 1 && execname == strstr(execname, COMMAND))/ 
 {
        /* print optional fields */
        OPT_time ? printf("%-14d ", timestamp/1000) : 1;
        OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
        OPT_zone ? printf("%-10s ", zonename) : 1;
        OPT_proj ? printf("%5d ", curpsinfo->pr_projid) : 1;

        /* print main data */
        /* APPLE: Removed the zonename output, it has no meaning in darwin */
        OPT_dump ? printf("%d %d %d %d %d %s ", timestamp/1000,
            curpsinfo->pr_projid, uid, pid, ppid, execname) :
            printf("%5d %6d %6d ", uid, pid, ppid);
        OPT_safe ? printf("%S\n", curpsinfo->pr_psargs) :
            printf("%s\n", curpsinfo->pr_psargs);
 }
: probe description proc:::exec-success does not match any probes. System Integrity Protection is on

I inherited this code and in it calls strace from within python. In particular it calls:

def strace_build(executable: str,
                 regex: str,
                 workdir: Optional[str],
                 command: List[str],
                 strace_logdir=None) -> List[str]:
    ''' trace calls of executable during access to files that match regex
    in workdir while executing the command and  returns the list of pycoq_context 
    file names

    In the simplest case strace runs the specified command until it
    exits.  It intercepts and records the system calls which are
    called by a process and the signals which are received by a
    process.  The name of each system call, its arguments and its
    return value are printed on standard error or to the file
    specified with the -o option.

    https://mcmap.net/q/1297671/-how-to-call-an-equivalent-command-to-strace-on-mac-ideally-from-python
    '''
    print('---- Calling strace_build ----')

    def _strace_build(executable, regex, workdir, command, logdir):
        logfname = os.path.join(logdir, 'strace.log')
        logging.info(f"pycoq: tracing {executable} accesing {regex} while "
                     f"executing {command} from {workdir} with "
                     f"curdir {os.getcwd()}")
        print(f"pycoq: tracing {executable} accesing {regex} while "
              f"executing {command} from {workdir} with "
              f"curdir {os.getcwd()}")
        with subprocess.Popen(['strace', '-e', 'trace=execve',
                               '-v', '-ff', '-s', '100000000',
                               '-xx', '-ttt',
                               '-o', logfname] + command,
                              cwd=workdir,
                              text=True,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE) as proc:
            for line in iter(proc.stdout.readline, ''):
                logging.debug(f"strace stdout: {line}")
                print(f"strace stdout: {line=}")
            logging.info(f"strace stderr: {proc.stderr.read()}"
                         "waiting strace to finish...")
            proc.wait()
        logging.info('strace finished')
        res: list[str] = parse_strace_logdir(logdir, executable, regex)
        print('---- Done with strace_build ----')
        return res

    if strace_logdir is None:
        with tempfile.TemporaryDirectory() as _logdir:
            return _strace_build(executable, regex, workdir, command, _logdir)
    else:
        os.makedirs(strace_logdir, exist_ok=True)
        strace_logdir_cur = tempfile.mkdtemp(dir=strace_logdir)
        return _strace_build(executable, regex, workdir, command, strace_logdir_cur)

but because it calls strace it only works on linux. I want it to work on my mac -- ideally if possible in the most pythonic way possible. I believe what it does is strace a terminal command that is called from within python.

What would be an equivalent way to call this command on mac using the same flags so that it works (ideally exactly) the same?

Not sure if this matters but I am using an m1 mac.


some output when the above function is used:

--done with make attempt--
---- Calling strace_build ----
pycoq: tracing /home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc accesing .*\.v$ while executing ['opam', 'reinstall', '--yes', '--switch', 'ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1', '--keep-build-dir', 'debug_proj'] from None with curdir /home/bot
strace stdout: line='\n'
strace stdout: line='<><> Synchronising pinned packages ><><><><><><><><><><><><><><><><><><><><><><>\n'
strace stdout: line='[debug_proj.~dev] no changes from file:///home/bot/iit-term-synthesis/coq_projects/debug_proj\n'
strace stdout: line='\n'
strace stdout: line='debug_proj is not installed. Install it? [Y/n] y\n'
strace stdout: line='Sorry, no solution found: there seems to be a problem with your request.\n'
strace stdout: line='\n'
strace stdout: line='No solution found, exiting\n'
---- Done with strace_build ----
...
---- Calling strace_build ----
pycoq: tracing /home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc accesing .*\.v$ while executing ['make', '-C', '/home/bot/iit-term-synthesis/coq_projects/debug_proj'] from None with curdir /home/bot
strace stdout: line="make: Entering directory '/home/bot/iit-term-synthesis/coq_projects/debug_proj'\n"
strace stdout: line='coq_makefile -f _CoqProject -o CoqMakefile\n'
strace stdout: line='make --no-print-directory -f CoqMakefile \n'
strace stdout: line='COQDEP VFILES\n'
strace stdout: line='COQC debug_0_plus_n_eq_n.v\n'
strace stdout: line='COQC debug1_n_plus_1_greater_than_n.v\n'
strace stdout: line='COQC debug2_n_plus_0_eq_n.v\n'
strace stdout: line="make: Leaving directory '/home/bot/iit-term-synthesis/coq_projects/debug_proj'\n"
---- Done with strace_build ----

def strace_build_mac_m1(executable: str,
                 regex: str,
                 workdir: Optional[str],
                 command: List[str],
                 strace_logdir=None) -> List[str]:
    ''' trace calls of executable during access to files that match regex
    in workdir while executing the command and  returns the list of pycoq_context
    file names

    In the simplest case strace runs the specified command until it
    exits.  It intercepts and records the system calls which are
    called by a process and the signals which are received by a
    process.  The name of each system call, its arguments and its
    return value are printed on standard error or to the file
    specified with the -o option.

    https://mcmap.net/q/1297671/-how-to-call-an-equivalent-command-to-strace-on-mac-ideally-from-python

    plan:
    - get the command we are running
    - pip push my pycoq with no name changes so code doesn't break
    - pull the rest of the repos needed, I don't think anything else since lf is here
    - harcode test
    - actually, look at commands...we need to provide for reproducibility a way to install opam and all this stuff
    without docker but in the mac since we are trying to do a mac install. Argh...

    COMMANDS:
    pycoq: tracing /home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc accesing .*\.v$ while executing ['opam', 'reinstall', '--yes', '--switch', 'ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1', '--keep-build-dir', 'lf'] from None with curdir /home/bot
    executable='/home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc'
    regex='.*\\.v$'
    workdir=None
    command=['opam', 'reinstall', '--yes', '--switch', 'ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1', '--keep-build-dir', 'lf']
    curdir: os.getcwd()='/home/bot'
    '''
    print('---- Calling strace_build_mac_m1 ----')

    def _strace_build(executable, regex, workdir, command, logdir):
        logfname = os.path.join(logdir, 'strace.log')
        logging.info(f"pycoq: tracing {executable} accesing {regex} while "
                     f"executing {command} from {workdir} with "
                     f"curdir {os.getcwd()}")
        print(f"pycoq: tracing {executable} accesing {regex} while "
              f"executing {command} from {workdir} with "
              f"curdir {os.getcwd()}")
        print(f'{executable=}')
        print(f'{regex=}')
        print(f'{workdir=}')
        print(f'{command=}')
        print(f'curdir: {os.getcwd()=}')
        with subprocess.Popen(['dtruss', '-e', 'trace=execve',
                               '-v', '-ff', '-s', '100000000',
                               '-xx', '-ttt',
                               '-o', logfname] + command,
                              cwd=workdir,
                              text=True,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE) as proc:
            for line in iter(proc.stdout.readline, ''):
                logging.debug(f"strace stdout: {line}")
                print(f"strace stdout: {line=}")
            logging.info(f"strace stderr: {proc.stderr.read()}"
                         "waiting strace to finish...")
            proc.wait()
        logging.info('strace finished')
        res: list[str] = parse_strace_logdir(logdir, executable, regex)
        print('---- Done with strace_build_mac_m1 ----')
        return res

    if strace_logdir is None:
        with tempfile.TemporaryDirectory() as _logdir:
            return _strace_build(executable, regex, workdir, command, _logdir)
    else:
        os.makedirs(strace_logdir, exist_ok=True)
        strace_logdir_cur = tempfile.mkdtemp(dir=strace_logdir)
        return _strace_build(executable, regex, workdir, command, strace_logdir_cur)


# -

def code_for_mac_m1():
    coq_package = 'lf'
    coq_package_pin = '~/pycoq/pycoq/test/lf'
    coq_package_pin = os.path.expanduser(coq_package_pin)

    print(f'coq_package: {coq_package=}')
    print(f'coq_package_pin: {coq_package_pin=}')


    ### pycoq: tracing /home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc accesing .*\.v$ while executing ['opam', 'reinstall', '--yes', '--switch', 'ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1', '--keep-build-dir', 'lf'] from None with curdir /home/bot
    # executable='/home/bot/.opam/ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1/bin/coqc'
    # regex='.*\\.v$'
    # workdir=None
    # command=['opam', 'reinstall', '--yes', '--switch', 'ocaml-variants.4.07.1+flambda_coq-serapi.8.11.0+0.11.1', '--keep-build-dir', 'lf']
    # curdir: os.getcwd()='/home/bot'

    # - get the filename in split
    # path2filenames: list[str] = pycoq.opam.opam_strace_build(coq_proj, coq_proj_pin)
    path2filenames_raw: list[str] = strace_build_mac_m1()
    path2filenames_raw.sort()
    print(f'\n====----> Populate coq pkg/proj data with files: {path2filenames_raw=}')


if __name__ == '__main__':
    code_for_mac_m1()
    print('Done!\n\a')

why doesn't this meet the SO guidelines? I am not asking for a software request clearly. From the discussion it's much harder to run in python + having the mac setup as needed + the tool with the equivalent flags to strace for mac.


google for replacement (analogue) of functionality of strace for Mac OS and modify the parser that parses output of strace for that “mac-strace” The strace functionality is used to inspect the Coq building system to record all options and arguments and environment for coqc in which each individual .v file has be processed by coqc during the build process. The Coq build system is complicated, and i didn’t parse but resolved to just observing by strace of what the actual Coq does and strace simply records all options and arguments (like -R etc) of what the actual Coq does so that pycoq could call coqc with exactly the same options and arguments


Using modified dtruss.sh

Answer by philipe didn't work:

(meta_learning) brandomiranda~ ❯ cat dtruss.sh
#!/bin/bash

file=$(type -P $1); shift
c=/tmp/$(basename "$file")
cp "$file" "$c"
codesign --remove-signature "$c"
sudo dtruss "$c" "$@"
(meta_learning) brandomiranda~ ❯ chmod +x dtruss.sh
(meta_learning) brandomiranda~ ❯ ./dtruss.sh echo hi

dtrace: system integrity protection is on, some features will not be available

dtrace: failed to execute /tmp/echo: Could not create symbolicator for task

To fix sudo to not prompt for password see:

# root and users in group wheel can run anything on any machine as any user
root        ALL = (ALL) ALL
%admin      ALL = (ALL) NOPASSWD: ALL
#%admin     ALL = (ALL) ALL

Related:

Haematoblast answered 14/9, 2022 at 23:13 Comment(20)
The options are... not great. Apple ships with dtruss, but it hasn't been well-maintained for a few releases now, and won't trace vendor-provided binaries used without modification unless you weaken your system's security settings.Threefold
There's Apple's own Instruments tool included in XCode, but its traces are in a binary format, and I don't know that it's documented.Threefold
Also, this smells a lot like a tool recommendation request, and those are categorically off-topic.Threefold
One recently-developed tool (open-source, but with a GUI frontend) is Crescendo, the blog post introducing it (linked prior) provides a lot of useful/relevant background about the state of tracing tools on MacOS, and why recent security changes have made so many obsolete.Threefold
given that you just want to follow exec calls, I suggest looking at dtrace and execsnoop and tailoring that to your needs. the strace facility in macos is locked down , and as people mentioned it isn't well maintained.Hierarch
...if you really just care about execve operations, btw, Process Monitor is relevant. Gives you a nice JSON description of everything going on.Threefold
why doesn't this meet the SO guidelines? I am not asking for a software request clearly. From the discussion it's much harder to run in python + having the mac setup as needed + the tool with the equivalent flags to strace for mac.Haematoblast
Why not install strace externally from your favourite package manager, say brew as in here? You already have root privilege, don't you? This way strace will be called normally in MacOS with full compatibility.Hort
@BilalQandeel I can't remember what happened when I tried that. Will try again. But the binaries are for x86 and my Mac is an m1 chip/arm. I wonder if it will give me issues. I'm fine trying to use apples translation tool btw x86 and arm of I have too. Idk how though or the name of the tool right now. If you have suggestions feel free to ping me!Haematoblast
Are you sure it is not available for mac? There is a homebrew formula available formulae.brew.sh/formula/straceLempira
@DialFrost I don't know how to use his answer with my m1 arm machine + set up the security settings in my Mac so that it would work anyway...Haematoblast
Does this help? @CharlieParker, It's about DTrace that is found on macos but not linux or windowsSongster
Unfortunately DTrace is only for D-language, but there are ways to use it with python. If DTrace happens to answer your QNS, I can form an answerSongster
Also, I cannot form the exact same output you want unfortunately, only provide some information about it and how to use itSongster
@Songster not 100% sure if it would solve it...but if you give me the equivalent command to the strace one I proviede I could test it and report back if it worked. Sounds promising!Haematoblast
Note that I have 0 experience in this sorta stuf, so I probably can't be experienced enough to give the equivalent command to the strace you provided unfortunatelySongster
related: #31046075 tracing sys calls in macHaematoblast
is it possible to run dtruss without doing the odd things suggested here: https://mcmap.net/q/577911/-mac-osx-using-dtrussHaematoblast
@CharlieParker I just added an answer, it may not be the answer you hoped. But for macOS 13.2 and future releases, you will not be seeing this type of functionality in macOS without using Apple's entitlement system.Peraea
Were any of the new answers helpful to you? Did you have questions on my answer?Peraea
P
8

Most of the answers and workarounds in the question are attempting to work inside the Linux security model. For a number of years, Apple has steadily increased their security beyond their Mach/BSD roots. They have added Hardware security that secures the system from booot to full macOS load. The Secure Enclave also processes face and fingerprint data. FileVault can encrypt your entire disk. System Integrity Protection provides a rootless system where root has little more permissions than the nobody user. For example, on a Ventura 13.2 system, root can not see every file or directory (sudo find / -print|wc produces many "Operation not permitted" errors).

In short, the only viable method to trace execution like this has a number of hefty requirements:

  • You must use Apple's EndpointSecurity framework.
  • Your code must be compiled in Xcode as an Application Bundle (Program.app installed in /Applications).
  • You will need Apple to grant your developer account the 'com.apple.developer.endpoint-security.client' entitlement.
  • You will need to assign a Provisioning Profile to codesign with the granted entitlement.
  • If you have not been granted the entitlement, you must disable System Integrity Protection (SIP) in recovery mode and disable Apple Mobile File Integrity (AMFI). Both of these actions are strongly discouraged, as they are mostly responsible for securing your system (and preventing you from running dtruss/strace).
  • Your application must run as root.
  • Your application must be granted 'Full Disk Access' from the 'Security & Privacy' System Preferences pane.

You could then write a complete replacement for strace as an application bundle (/Application/strace.app) and use it as such:

/Applications/strace.app/Contents/MacOS/strace -e trace=execve -v -s 100000000 -xx -ttt -ff -o output.txt sh -c 'echo hi'

The various suggestions in the other answers fail for different reasons:

  • The use of dtrace now requires SIP to be disabled.
  • If you could port strace to macOS, it would also require SIP to be disabled.
  • Also in 13.2, execsnoop requires SIP:

% sudo execsnoop -a -c ./test
probe description proc:::exec-success does not match any probes. System Integrity Protection is on

  • Using a LD_PRELOAD is challenging, see this developer forum thread.
  • Removing the signature with codesign --remove-signature now results in the process being killed.

    ASP: Security policy would not allow process

My suggestion:

Rewrite the code to not use strace on either Linux or macOS and build a framework to get the information you need during the build directly. At some point, Linux will also add these type of security features. Maybe not this year, but I'd think before the end of the decade.

Bonus:

If you wish to implement the application I suggested above, this gist is a start. Charles Duffy linked a derivative of that gist above.

Peraea answered 12/3, 2023 at 2:59 Comment(0)
C
3

If you don't want to disable System Integrity Protection (SIP) with csrutil, it seems that the only option is to remove the signature with codesign.

I made a little script to simplify the process, save following in dtruss.sh

#!/bin/bash

file=$(type -P $1); shift
c=/tmp/$(basename "$file")
cp "$file" "$c"
codesign --remove-signature "$c"
sudo dtruss "$c" "$@"

then

chmod +x dtruss.sh
./dtruss.sh echo hi
./dtruss.sh find /etc/ -name bashrc

Update

  1. See Enable sudo without a password on MacOS

  2. It works on my Ventura 13.1 Intel

$ ./dtruss.sh echo "Hello, World!"
dtrace: system integrity protection is on, some features will not be available

SYSCALL(args)        = return
Hello, World!
mprotect(0x1105F0000, 0x8000, 0x1)       = 0 0
thread_selfid(0x0, 0x0, 0x0)         = 19299 0
shared_region_check_np(0x7FF7BAE92940, 0x0, 0x0)         = 0 0
thread_selfid(0x0, 0x0, 0x0)         = 19299 0
...

Sudo-ing without a password mac

For the millionth time, I upgraded macOS to the next major version (Monterey) and I had to search for how to re-enable password-less sudo’ing.

edit /etc/sudoers

   sudo visudo

Then find the admin group permission section:

   %admin          ALL = (ALL) ALL

Change to add NOPASSWD:

   %admin          ALL = (ALL) NOPASSWD: ALL

Profit until next year.

Crawler answered 25/2, 2023 at 18:4 Comment(10)
two issues: 1. it prompts me for a password. I will be running this command through pycharm so I need to be able to run it without manually typing my password. Hardcoding the password in dstruss.sh is fine. 2. it didn't work. Error: dtrace: system integrity protection is on, some features will not be available dtrace: failed to execute /tmp/echo: Could not create symbolicator for task Did you try it in your computer?Haematoblast
crucial links inside an SO question is bad practice e.g. lik might go down. I will edit to put in the content needed.Haematoblast
this still didn't work for me :( same errorHaematoblast
@CharlieParker What is your MacOS version ? Can you post the result of codesign -d -vvv --deep /bin/echo, and codesign -d -vvv --deep /tmp/echo, and uanme -aCrawler
@Crawler this last worked on 13.1, for 13.2 forward you need to use Apple's EndpointSecurity framework for tracing (dtruss/strace like monitoring).Peraea
@JamesRisner I upgraded to 13.2.1, it still works.Crawler
Interesting, it hasn't worked for me on any the machines I own (3 of them) since 13.2. So I guess it's currently a bug in 13.2.Peraea
@JamesRisner Do you mean Apple has not deployed EndpointSecurity framework on 13.2.x yet ?Crawler
They deployed in Big Sur, if I recall. It works. I use it. It's the "future" for anything remotely close to this type of info on macOS.Peraea
Here, they only mention as a Sample Code ProjectCrawler
C
1

The short and simple answer is that the security model of MacOS is inherently different. The standard tool for tracing system calls (and much, much more) on BSD-based systems is dtruss, but it's quite different from strace; for starters, it requires you to be root to even start exploring what's possible.

Since it's not clear if that's a route you want to take, I will just briefly link to a few resources for further information.

So, in very brief, it is unlikely that you can easily extend this code to be portable between Linux and MacOS.

Perhaps a plausible alternative would be to extend the software you are attempting to strace to instead provide some sort of internal debugging mode to emit an event or print a message each time it dispatches an "interesting" system call. Depending on what's "interesting", this can be anywhere from moderately trivial to extremely challenging.

Another possible avenue to explore would be a wrapper for the system calls you are interested in. You could simply print out the arguments, then proceed to call the proper system call. See e.g. DYLD_LIBRARY_PATH & DYLD_INSERT_LIBRARIES not working (The equivalent facility on Linux is called LD_PRELOAD.)

Cioffi answered 9/10, 2022 at 9:57 Comment(2)
What about strace using home brew? formulae.brew.sh/formula/strace I think the only two issues I'm having is 1. If that still requires me to change my security settings and 2. If it works on a m1 arm mac instead of an x86. Do you know?Haematoblast
I think you already got overwhelming responses to your comments elsewhere earlier to tell you that it doesn't. I have no experience.Cioffi
H
1

Please check the following two scripts based on this book. I believe these two combined will give you a similar result as the original code.

I fixed the script to be compatible to new version. It runs on my M1. Not sure if I am getting the expected output. Please read the book for more information.

#openproc.py ( Fixed to newer_version)
#!/usr/bin/env python
import re
import sys
# ----------------------------
# openproc.py - Collect data from opentrace.py and merge :entry and :return →
# Open trace file or use stdin
try:
    inf = file(sys.argv[1], 'r')
except OSError as ose:
    print(ose)
    print('''openproc.py [filename]''')
    sys.exit(1)
except IndexError:
    inf = sys.stdin
# Convert time to human time
def human_time(ns):
    ns = float(ns)
    for unit in ['ns', 'us', 'ms']:
        if abs(ns) == 0:
            print('ERROR %d' % ret)
        else:
            print('OPEN %s %d %s => %s [%s]' % (users.get(uid, str(uid)),
                                            pid, state[pid][1], status,
                                            human_time(tm - state[pid][0])))
        del state[pid]
#opentrace.py (Fixed syntax)
#!/usr/bin/env python
import sys, os, subprocess, platform
from optparse import OptionParser
# ----------------------------
# opentrace.py - Trace open syscalls via SystemTap or DTrace
# supports filtering per UID or PID
optparser = OptionParser()
optparser.add_option('-S', '--stap', action='store_true',
                     dest='systemtap', help='Run SystemTap')
optparser.add_option('-D', '--dtrace', action='store_true',
                     dest='dtrace', help='Run DTrace')
optparser.add_option('-p', '--pid', action='store', type='int',
                     dest='pid', default='-1', metavar='PID',
                     help='Trace process with specified PID')
optparser.add_option('-u', '--uid', action='store', type='int',
                     dest='uid', default='-1', metavar='UID',
                     help='Filter traced processes by UID')
optparser.add_option('-c', '--command', action='store', type='string',
                     dest='command', metavar='CMD',
                     help='Run specified command CMD and trace it')
(opts, args) = optparser.parse_args()
if opts.pid >= 0 and opts.command is not None:
    optparser.error('-p and -c are mutually exclusive')
if (opts.pid >= 0 or opts.command is not None) and opts.uid >= 0:
     optparser.error('-p or -c are mutually exclusive with -u')
if opts.systemtap and opts.dtrace:
    optparser.error('-S and -D are mutually exclusive')
if not opts.systemtap and not opts.dtrace:
    # Try to guess based on operating system
    opts.systemtap = sys.platform == 'linux2'
    opts.dtrace = sys.platform == 'sunos5'
if not opts.systemtap and not opts.dtrace:
    optparser.error('DTrace or SystemTap are non-standard for your platform,please specify -S or -D option')
def run_tracer(entry, ret, cond_proc, cond_user, cond_default,
               env_bin_var, env_bin_path,
               opt_pid, opt_command, args, fmt_probe):
    cmdargs = [os.getenv(env_bin_var, env_bin_path)]
    if opts.pid >= 0:
        cmdargs.extend([opt_pid, str(opts.pid)])
        entry['cond'] = ret['cond'] = cond_proc
    elif opts.command is not None:
        cmdargs.extend([opt_command, opts.command])
        entry['cond'] = ret['cond'] = cond_proc
    elif opts.uid >= 0:
        entry['cond'] = ret['cond'] = cond_user % opts.uid
    else:
        entry['cond'] = ret['cond'] = cond_default
    cmdargs.extend(args)
    proc = subprocess.Popen(cmdargs, stdin=subprocess.PIPE)
    proc.stdin.write(fmt_probe % entry)
    proc.stdin.write(fmt_probe % ret)
    proc.stdin.close()
    proc.wait()

if opts.systemtap:
    entry = {'name': 'syscall.open',
             'dump': '''printf("=> uid: %d pid: %d open: %s %d\\n",
                        uid(), pid(), filename, gettimeofday_ns());'''}
    ret =   {'name': 'syscall.open.return',
             'dump': '''printf(" uid: %%d pid: %%d open: %%s %%lld\\n",
        uid, pid, copyinstr(%s), (long long) timestamp); ''' % fn_arg}
Householder answered 15/10, 2022 at 23:6 Comment(0)
S
0

I have no experience in this, but I'll try my best.

You can use the DTrace.

Here are some commands from Oracle docs - DTrace command line:

dtrace [-CeFGhHlqSvVwZ]
[-b bufsz] [-c command] [-D name[=value]] [-I pathname] [-L pathname]
[-o pathname] [-p PID] [-s source_pathname]
[-U name] [-x option[=value]][-X[a|c|s|t]]
[-P provider[[predicate]action]]
[-m [[provider:]module[[predicate]action]]]
[-f [[provider:]module:]function[[predicate]action]]
[-n [[[provider:]module:]function:]name[[predicate]action]]
[-i probe-id[[predicate]action]]

Now apparently this only operates in the D-language, but there are many githubs online that can handle this with python.

There is this particular Github by @paulross, where the preparation of creating a dtrace version of Python and a virtual environment in the ~/venvs directory (or wherever you prefer):

cd ~/tmp
curl -o Python-3.7.0.tgz https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tgz
tar -xzf Python-3.7.0.tgz
cd Python-3.7.0
./configure --with-dtrace
make
python.exe -m venv ~/venvs/dtrace

Unfortunately I cannot provide the exact code using dtrace that is used with strace due to my inexperience in this.

Here's an enormously long and comprehensive book on DTrace

Songster answered 13/10, 2022 at 3:10 Comment(0)
H
-2

See: https://mcmap.net/q/1297671/-how-to-call-an-equivalent-command-to-strace-on-mac-ideally-from-python


Change no more password sudo in mac

original:

# root and users in group wheel can run anything on any machine as any user
root            ALL = (ALL) ALL
%admin          ALL = (ALL) ALL

change

   %admin          ALL = (ALL) NOPASSWD: ALL

Haematoblast answered 14/9, 2022 at 23:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.