Architektur von Prozessen rausfinden

  • Architektur von Prozessen rausfinden

    Hi,

    über den NSWorkspace kann ich mir ja ne Liste von laufenden Programmen und deren PIDs und so holen.
    Gibts irgendwie eine ähnlich einfache Möglichkeit, die von einem Programm genutzte Prozessorarchitektur rauszufinden?
    Kann ja sein, dass es ein x86, x64 oder ppc (halt via Rosetta) Programm ist.
    Mich würde dann die wirklich genutzte Architektur interessieren (nicht, dass via Häkchen im Finder PPC statt Intel oder 32 bit statt 64 benutzt wird).
    Achso, der Code sollte ab 10.5 laufen, früher ist natürlich immer besser ;)

    Danke euch schonmal :)
  • Ab 10.6 gibt es developer.apple.com/mac/librar…on/executableArchitecture

    Für ältere Versionen gibt es vermutlich nur die Holzhammermethode über die PID und irgendwelche alten und verbotenen Carbon- (vielleicht über GetProcessForPID und GetProcessInformation oder so) oder Mach-APIs (etwa task_for_pid und dann die passenden Threadinformationen auslesen).

    Wozu willst du aber eigentlich wissen mit welcher Architektur ein Prozess gerade läuft?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von system ()

  • Mit dem Komandozeilenprogramm file (1) kannst Du die verfügbaren Prozessorarchitekturen eines Programms erfragen:

    Quellcode

    1. file /Applications/TextEdit.app/Contents/MacOS/TextEdit
    2. /Applications/TextEdit.app/Contents/MacOS/TextEdit: Mach-O universal binary with 2 architectures
    3. /Applications/TextEdit.app/Contents/MacOS/TextEdit (for architecture x86_64): Mach-O 64-bit executable x86_64
    4. /Applications/TextEdit.app/Contents/MacOS/TextEdit (for architecture i386): Mach-O executable i386


    Bei laufenden Prozessen kannst Du die verwendete Architektur auch über den Activity Monitor sehen.
    „Meine Komplikation hatte eine Komplikation.“
  • Schonmal danke für die Antworten :)
    Wäre mir halt ganz recht, wenn ich auch eine Methode für 10.5 hätte... Aber naja, vllt nehm ich erstmal die 10.6er Variante.
    Ansich würde mir ja sogar die Info, die top rausgibt schon reichen: das Zeichen hinter der PID (+, -, *) sagt schon alles was ich brauche. Wollte das aber halt doch etwas "schöner" machen als über nen command line programm...
    Brauche das ganze für das Projekt hier: ingamium.games4mac.de/

    kurze Zusammenfassung des Problems:
    Ich benutze da mach_inject um Code in einen laufenden Prozess einzuleiten. Und dazu muss ich halt vorher wissen, was für ein Prozess das ist.
    Gehe halt standardmäßig von x86 aus. Ists ein x64-Prozess (noch relativ selten, gerade bei Spielen), passiert einfach nichts, mach_inject merkt das und bricht ab. Wenn ich das vorher wüsste könnte ich halt vorkehrungen treffen dass es funktioniert. Ich kann jetzt ja aber auch nicht einfach hergehen und mir z.B. merken, dass das Programm "VLC" 64-bit ist, dann würde es ja bei Nutzern mit 32bit-Macs oder alten, 32bit-Versionen nicht mehr klappen...
    Versuche ich das ganze aber bei einem via Rosetta ausgeführten PPC-Prozess, dann knallts: mach_inject merkt nicht, dass es kein x86-Prozess ist (ist wegen Rosetta ansich ja quasi einer) und injected den Code, was bei dem intern verwendeten ppc-code aber nicht so gut klappt ;)
    Wenn ich vorher halt wüsste, was es genau für ein Prozess ist, ließen sich die Fehler abfangen. Tritt alles nicht soo häufig auf, ppc stirbt langsam aus und x64 wird bei Spielen nicht so benötigt, aber schaden tuts ja nicht...
  • opensource.apple.com/source/top/top-67/libtop.c

    Quellcode

    1. /*
    2. * Return the CPU type of the process.
    3. */
    4. static libtop_status_t
    5. libtop_p_cputype(pid_t pid, cpu_type_t *cputype) {
    6. int res = -1;
    7. static int mib[CTL_MAXNAME];
    8. static size_t miblen = 0;
    9. *cputype = 0;
    10. if (miblen == 0) {
    11. miblen = CTL_MAXNAME;
    12. res = sysctlnametomib("sysctl.proc_cputype", mib, &miblen);
    13. if (res != 0) {
    14. miblen = 0;
    15. }
    16. }
    17. if (miblen > 0) {
    18. mib[miblen] = pid;
    19. size_t len = sizeof(*cputype);
    20. res = sysctl(mib, miblen + 1, cputype, &len, NULL, 0);
    21. }
    22. /* res will be 0 if the sysctl was successful. */
    23. return (res == 0) ? LIBTOP_NO_ERR : LIBTOP_ERR_INVALID;
    24. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von system ()

  • Ich habe das jetzt mal gebraucht, aber weil ich noch andere Informationen zu einer PID haben will, habe ich folgenden alternative weg gefunden, der mir zwei sysctl-calls spart. Ist jetzt aber nur, um zu testen ob 32bit oder 64bit x86 -- gute Frage, was bei PPC passiert...findet sich aber evtl. auch noch was in <sys/sysctl.h> und <sys/proc.h>

    C-Quellcode

    1. int mib[4];
    2. struct kinfo_proc p;
    3. size_t buf_size;
    4. mib[0] = CTL_KERN;
    5. mib[1] = KERN_PROC;
    6. mib[2] = KERN_PROC_PID;
    7. mib[3] = pid_;
    8. buf_size = sizeof(p);
    9. int err = sysctl(mib, 4, &p, &buf_size, NULL, 0);
    10. if(0==err) {
    11. /* No error, success! */
    12. if(p.kp_proc.p_pid!=pid_) {
    13. /* this is pretty hacky, but works.. */
    14. throw zexception("pid (%d) is invalid", pid_);
    15. } else {
    16. /** collect info we want **/
    17. svuid_ = p.kp_eproc.e_pcred.p_svuid; /// user-id des prozess-besitzers; uid_t
    18. procname_ = std::string(p.kp_proc.p_comm); /// kurz-name des entsprechenden prozesses
    19. lp64_ = p.kp_proc.p_flag & P_LP64; /// 64bit?? lp64_ ist vom typ bool
    20. }
    21. } else {
    22. throw zexception("sysctl failed: %d", err);
    23. }
    Alles anzeigen
    C++