Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  task_dumper.rs   Sprache: unbekannt

 
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

//! All of these tests are specific to the MacOS task dumper
#![cfg(target_os = "macos")]

use minidump_writer::{mach::LoadCommand, task_dumper::TaskDumper};
use std::fmt::Write;

fn call_otool(args: &[&str]) -> String {
    let mut cmd = std::process::Command::new("otool");
    cmd.args(args);

    let exe_path = std::env::current_exe().expect("unable to retrieve test executable path");
    cmd.arg(exe_path);

    let output = cmd.output().expect("failed to spawn otool");

    assert!(output.status.success());

    String::from_utf8(output.stdout).expect("stdout was invalid utf-8")
}

/// Validates we can iterate the load commands for all of the images in the task
#[test]
fn iterates_load_commands() {
    let lc_str = call_otool(&["-l"]);

    let mut expected = String::new();
    let mut lc_index = 0;

    expected.push('\n');

    while let Some(nlc) = lc_str[lc_index..].find("Load command ") {
        lc_index += nlc;

        let block = match lc_str[lc_index + 13..].find("Load command ") {
            Some(ind) => &lc_str[lc_index + 13..lc_index + 13 + ind],
            None => &lc_str[lc_index..],
        };

        // otool prints the load command index for each command, but we only
        // handle the small subset of the available load commands we care about
        // so just ignore that
        let block = &block[block.find('\n').unwrap() + 1..];

        // otool also prints all the sections for LC_SEGMENT_* commands, but
        // we don't care about those, so ignore them
        let block = match block.find("Section") {
            Some(ind) => &block[..ind],
            None => block,
        };

        lc_index += 13;

        let cmd = block
            .find("cmd ")
            .expect("load commnd didn't specify cmd kind");
        let cmd_end = block[cmd..]
            .find('\n')
            .expect("load cmd didn't end with newline");
        if matches!(
            &block[cmd + 4..cmd + cmd_end],
            "LC_SEGMENT_64" | "LC_UUID" | "LC_ID_DYLIB" | "LC_LOAD_DYLINKER"
        ) {
            expected.push_str(block);
        }
    }

    let task_dumper = TaskDumper::new(
        // SAFETY: syscall
        unsafe { mach2::traps::mach_task_self() },
    );

    let mut actual = String::new();

    // Unfortunately, Apple decided to move dynamic libs into a shared cache,
    // removing them from the file system completely, and unless I'm missing it
    // there is no way to get the load commands for the dylibs since otool
    // only understands file paths? So we just get the load commands for the main
    // executable instead, this means that we miss the `LC_ID_DYLIB` commands
    // since they only apply to dylibs, but this test is more that we can
    // correctly iterate through the load commands themselves, so this _should_
    // be fine...
    let exe_img = task_dumper
        .read_executable_image()
        .expect("failed to read executable image");

    {
        let lcmds = task_dumper
            .read_load_commands(&exe_img)
            .expect("failed to read load commands");

        for lc in lcmds.iter() {
            match lc {
                LoadCommand::Segment(seg) => {
                    let segname = std::str::from_utf8(&seg.segment_name).unwrap();
                    let segname = &segname[..segname.find('\0').unwrap()];
                    write!(
                        &mut actual,
                        "
      cmd LC_SEGMENT_64
  cmdsize {}
  segname {}
   vmaddr 0x{:016x}
   vmsize 0x{:016x}
  fileoff {}
 filesize {}
  maxprot 0x{:08x}
 initprot 0x{:08x}
   nsects {}
    flags 0x{:x}",
                        seg.cmd_size,
                        segname,
                        seg.vm_addr,
                        seg.vm_size,
                        seg.file_off,
                        seg.file_size,
                        seg.max_prot,
                        seg.init_prot,
                        seg.num_sections,
                        seg.flags,
                    )
                    .unwrap();
                }
                LoadCommand::Dylib(_dylib) => {
                    unreachable!();
                }
                LoadCommand::Uuid(uuid) => {
                    let id = uuid::Uuid::from_bytes(uuid.uuid);
                    let mut uuid_buf = [0u8; uuid::fmt::Hyphenated::LENGTH];
                    let uuid_str = id.hyphenated().encode_upper(&mut uuid_buf);

                    write!(
                        &mut actual,
                        "
     cmd LC_UUID
 cmdsize {}
    uuid {uuid_str}
",
                        uuid.cmd_size,
                    )
                    .unwrap();
                }
                LoadCommand::DylinkerCommand(dy_cmd) => {
                    write!(
                        &mut actual,
                        "
          cmd LC_LOAD_DYLINKER
      cmdsize {}
         name {} (offset {})",
                        dy_cmd.cmd_size, dy_cmd.name, dy_cmd.name_offset,
                    )
                    .unwrap();
                }
            }
        }
    }

    similar_asserts::assert_eq!(expected, actual);
}

[ Dauer der Verarbeitung: 0.36 Sekunden  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge