Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/minidump/tests/   (Firefox Browser Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 12 kB image not shown  

Quelle  test_minidump.rs

  Sprache: Rust
 

// Copyright 2015 Ted Mielczarek. See the COPYRIGHT
// file at the top-level directory of this distribution.

use debugid::{CodeId, DebugId};
use minidump::system_info::{Cpu, Os};
use minidump::*;
use minidump_common::format as md;
use num_traits::cast::FromPrimitive;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;
use std::time::SystemTime;

fn get_test_minidump_path(filename: &str) -> PathBuf {
    let mut path = PathBuf::from(file!());
    path.pop();
    path.pop();
    path.pop();
    path.push("../");
    path.push("testdata");
    path.push(filename);
    println!("{path:?}");
    path
}

fn read_test_minidump() -> Result<MmapMinidump, Error> {
    let path = get_test_minidump_path("test.dmp");
    Minidump::read_path(path)
}

fn read_linux_minidump() -> Result<MmapMinidump, Error> {
    let path = get_test_minidump_path("linux-mini.dmp");
    Minidump::read_path(path)
}

#[ctor::ctor]
fn init_logger() {
    env_logger::builder().is_test(true).init();
}

#[test]
fn test_minidump_read_path() {
    read_test_minidump().unwrap();
}

#[test]
fn test_minidump_read() {
    let path = get_test_minidump_path("test.dmp");
    let mut f = File::open(path).unwrap();
    let mut buf = vec![];
    f.read_to_end(&mut buf).unwrap();
    let _dump = Minidump::read(buf).unwrap();
}

#[test]
fn test_module_list() {
    let dump = read_test_minidump().unwrap();
    let module_list = dump.get_stream::<MinidumpModuleList>().unwrap();
    assert_eq!(
        module_list.module_at_address(0x400000).unwrap().code_file(),
        "c:\\test_app.exe"
    );
    let modules = module_list.iter().collect::<Vec<_>>();
    let module_files = modules.iter().map(|m| m.code_file()).collect::<Vec<_>>();
    assert_eq!(modules.len(), 13);
    assert_eq!(modules[0].base_address(), 0x400000);
    assert_eq!(modules[0].size(), 0x2d000);
    assert_eq!(modules[0].code_file(), "c:\\test_app.exe");
    assert_eq!(
        modules[0].code_identifier().unwrap(),
        CodeId::new("45D35F6C2d000".to_string())
    );
    assert_eq!(modules[0].debug_file().unwrap(), "c:\\test_app.pdb");
    assert_eq!(
        modules[0].debug_identifier().unwrap(),
        DebugId::from_breakpad("5A9832E5287241C1838ED98914E9B7FF1").unwrap()
    );
    assert!(modules[0].version().is_none());

    assert_eq!(modules[12].base_address(), 0x76bf0000);
    assert_eq!(modules[12].size(), 0xb000);
    assert_eq!(modules[12].code_file(), "C:\\WINDOWS\\system32\\psapi.dll");
    assert_eq!(
        modules[12].code_identifier().unwrap(),
        CodeId::new("411096CAb000".to_string())
    );
    assert_eq!(modules[12].debug_file().unwrap(), "psapi.pdb");
    assert_eq!(
        modules[12].debug_identifier().unwrap(),
        DebugId::from_breakpad("A5C3A1F9689F43D8AD228A09293889702").unwrap()
    );
    assert_eq!(modules[12].version().unwrap(), "5.1.2600.2180");

    assert_eq!(
        module_files,
        vec![
            r"c:\test_app.exe",
            r"C:\WINDOWS\system32\ntdll.dll",
            r"C:\WINDOWS\system32\kernel32.dll",
            r"C:\WINDOWS\system32\ole32.dll",
            r"C:\WINDOWS\system32\advapi32.dll",
            r"C:\WINDOWS\system32\rpcrt4.dll",
            r"C:\WINDOWS\system32\gdi32.dll",
            r"C:\WINDOWS\system32\user32.dll",
            r"C:\WINDOWS\system32\msvcrt.dll",
            r"C:\WINDOWS\system32\imm32.dll",
            r"C:\WINDOWS\system32\dbghelp.dll",
            r"C:\WINDOWS\system32\version.dll",
            r"C:\WINDOWS\system32\psapi.dll",
        ]
    );

    assert_eq!(
        module_list
            .by_addr()
            .map(|m| m.code_file())
            .collect::<Vec<_>>(),
        vec![
            r"c:\test_app.exe",
            r"C:\WINDOWS\system32\dbghelp.dll",
            r"C:\WINDOWS\system32\imm32.dll",
            r"C:\WINDOWS\system32\psapi.dll",
            r"C:\WINDOWS\system32\ole32.dll",
            r"C:\WINDOWS\system32\version.dll",
            r"C:\WINDOWS\system32\msvcrt.dll",
            r"C:\WINDOWS\system32\user32.dll",
            r"C:\WINDOWS\system32\advapi32.dll",
            r"C:\WINDOWS\system32\rpcrt4.dll",
            r"C:\WINDOWS\system32\gdi32.dll",
            r"C:\WINDOWS\system32\kernel32.dll",
            r"C:\WINDOWS\system32\ntdll.dll",
        ]
    );
}

#[test]
fn test_system_info() {
    let dump = read_test_minidump().unwrap();
    let system_info = dump.get_stream::<MinidumpSystemInfo>().unwrap();
    assert_eq!(system_info.os, Os::Windows);
    assert_eq!(system_info.cpu, Cpu::X86);
    assert_eq!(
        system_info.cpu_info().unwrap(),
        "GenuineIntel family 6 model 13 stepping 8"
    );
    assert_eq!(&system_info.csd_version().unwrap(), "Service Pack 2");
}

#[test]
fn test_misc_info() {
    let dump = read_test_minidump().unwrap();
    let misc_info = dump.get_stream::<MinidumpMiscInfo>().unwrap();
    assert_eq!(misc_info.raw.process_id(), Some(&3932));
    assert_eq!(misc_info.raw.process_create_time(), Some(&0x45d35f73));
    assert_eq!(
        misc_info
            .process_create_time()
            .unwrap()
            .duration_since(SystemTime::UNIX_EPOCH)
            .unwrap()
            .as_secs(),
        1171480435// = 2007-02-14T19:13:55
    );
}

#[test]
fn test_breakpad_info() {
    let dump = read_test_minidump().unwrap();
    let breakpad_info = dump.get_stream::<MinidumpBreakpadInfo>().unwrap();
    assert_eq!(breakpad_info.dump_thread_id.unwrap(), 0x11c0);
    assert_eq!(breakpad_info.requesting_thread_id.unwrap(), 0xbf4);
}

#[test]
fn test_crashpad_info() {
    let path = get_test_minidump_path("simple-crashpad.dmp");
    let dump = Minidump::read_path(&path).unwrap();
    let crashpad_info = dump.get_stream::<MinidumpCrashpadInfo>().unwrap();

    let report_id = md::GUID {
        data1: 0x42F9_DE72,
        data2: 0x518A,
        data3: 0x43DD,
        data4: [0x97, 0xD7, 0x8D, 0xDC, 0x32, 0x8D, 0x36, 0x62],
    };
    assert_eq!(crashpad_info.raw.report_id, report_id);

    let client_id = md::GUID {
        data1: 0x6FD2_B3B9,
        data2: 0x9833,
        data3: 0x4B2F,
        data4: [0xBB, 0xF7, 0xB, 0xCF, 0x50, 0x1B, 0xAD, 0x7E],
    };
    assert_eq!(crashpad_info.raw.client_id, client_id);

    assert_eq!(crashpad_info.simple_annotations["hello"], "world");
    assert_eq!(crashpad_info.module_list.len(), 2);

    let module = &crashpad_info.module_list[0];
    assert_eq!(module.module_index, 16);
    assert_eq!(module.list_annotations, vec!["abort() called".to_owned()]);
    assert!(module.simple_annotations.is_empty());
    assert!(module.annotation_objects.is_empty());
}

#[test]
fn test_assertion() {
    let path = get_test_minidump_path("invalid-parameter.dmp");
    let dump = Minidump::read_path(&path).unwrap();
    let assertion = dump.get_stream::<MinidumpAssertion>().unwrap();
    assert_eq!(assertion.expression().unwrap(), "format != nullptr");
    assert_eq!(assertion.function().unwrap(), "common_vfprintf");
    assert_eq!(
        assertion.file().unwrap(),
        r"minkernel\crts\ucrt\src\appcrt\stdio\output.cpp"
    );
    assert_eq!(assertion.raw.line, 32);
    assert_eq!(
        md::AssertionType::from_u32(assertion.raw._type),
        Some(md::AssertionType::InvalidParameter)
    );
}

#[test]
fn test_exception() {
    let dump = read_test_minidump().unwrap();
    let exception = dump.get_stream::<MinidumpException>().unwrap();
    let system_info = dump.get_stream::<MinidumpSystemInfo>().unwrap();
    let misc_info = dump.get_stream::<MinidumpMiscInfo>().ok();
    assert_eq!(exception.thread_id, 0xbf4);
    assert_eq!(exception.raw.exception_record.exception_code, 0xc0000005);
    if let Some(ctx) = exception
        .context(&system_info, misc_info.as_ref())
        .as_deref()
    {
        assert_eq!(ctx.get_instruction_pointer(), 0x40429e);
        assert_eq!(ctx.get_stack_pointer(), 0x12fe84);
        if let MinidumpContext {
            raw: MinidumpRawContext::X86(ref raw),
            ref valid,
        } = *ctx
        {
            assert_eq!(raw.eip, 0x40429e);
            assert_eq!(*valid, MinidumpContextValidity::All);
        } else {
            panic!("Wrong context type");
        }
    } else {
        panic!("Missing context");
    }
}

#[test]
fn test_thread_list() {
    let dump = read_test_minidump().unwrap();
    let thread_list = dump.get_stream::<MinidumpThreadList<'_>>().unwrap();
    let system_info = dump.get_stream::<MinidumpSystemInfo>().unwrap();
    let misc_info = dump.get_stream::<MinidumpMiscInfo>().ok();
    let memory_list = dump.get_memory().unwrap_or_default();

    let threads = &thread_list.threads;
    assert_eq!(threads.len(), 2);
    assert_eq!(threads[0].raw.thread_id, 0xbf4);
    assert_eq!(threads[1].raw.thread_id, 0x11c0);
    let id = threads[1].raw.thread_id;
    assert_eq!(thread_list.get_thread(id).unwrap().raw.thread_id, id);
    if let Some(ctx) = threads[0]
        .context(&system_info, misc_info.as_ref())
        .as_deref()
    {
        assert_eq!(ctx.get_instruction_pointer(), 0x7c90eb94);
        assert_eq!(ctx.get_stack_pointer(), 0x12f320);
        if let MinidumpContext {
            raw: MinidumpRawContext::X86(ref raw),
            ref valid,
        } = *ctx
        {
            assert_eq!(raw.eip, 0x7c90eb94);
            assert_eq!(*valid, MinidumpContextValidity::All);
        } else {
            panic!("Wrong context type");
        }
    } else {
        panic!("Missing context");
    }
    if let Some(ref stack) = threads[0].stack_memory(&memory_list) {
        // Try the beginning
        assert_eq!(stack.get_memory_at_address::<u8>(0x12f31c).unwrap(), 0);
        assert_eq!(stack.get_memory_at_address::<u16>(0x12f31c).unwrap(), 0);
        assert_eq!(stack.get_memory_at_address::<u32>(0x12f31c).unwrap(), 0);
        assert_eq!(
            stack.get_memory_at_address::<u64>(0x12f31c).unwrap(),
            0x7c90e9c000000000
        );
        // And the end
        assert_eq!(stack.get_memory_at_address::<u8>(0x12ffff).unwrap(), 0);
        assert_eq!(stack.get_memory_at_address::<u16>(0x12fffe).unwrap(), 0);
        assert_eq!(stack.get_memory_at_address::<u32>(0x12fffc).unwrap(), 0);
        assert_eq!(
            stack.get_memory_at_address::<u64>(0x12fff8).unwrap(),
            0x405443
        );
    } else {
        panic!("Missing stack memory");
    }
}

#[test]
fn test_empty_minidump() {
    match Minidump::read(&b""[..]) {
        Ok(_) => panic!("Should have failed to read minidump"),
        Err(e) => assert_eq!(e, Error::MissingHeader),
    }
}

#[test]
fn backwards_range() {
    let data = include_bytes!("../../testdata/invalid-range.dmp");

    match Minidump::read(&data[..]) {
        Ok(f) => {
            // TODO verify this is correct
            // This seems to call `MinidumpStream::read()` with a `bytes` that is the entire
            // minidump!
            let _ = f
                .get_stream::<MinidumpLinuxMaps>()
                .expect_err("range should be invalid");
        }
        Err(e) => {
            panic!("Expected to parse the header, got {:?}", e);
        }
    }
}

#[test]
fn test_record_count_mac_info() {
    let data = include_bytes!("../../testdata/invalid-record-count.dmp");

    match Minidump::read(&data[..]) {
        Ok(f) => {
            let _ = f.get_stream::<MinidumpMacCrashInfo>();
        }
        Err(e) => {
            panic!("Expected to parse the header, got {:?}", e);
        }
    }
}

#[test]
fn test_linux_os_version() {
    let dump = read_linux_minidump().unwrap();
    let system_info = dump.get_stream::<MinidumpSystemInfo>().unwrap();

    assert_eq!(system_info.os_parts().0"4.9.60-linuxkit-aufs");
    assert_eq!(
        system_info.os_parts().1.unwrap(),
        "#1 SMP Mon Nov 6 16:00:12 UTC 2017",
    );
}

#[test]
fn test_full_dump_memory() {
    let path = get_test_minidump_path("full-dump.dmp");
    let dump = Minidump::read_path(&path).unwrap();
    let memory_list = dump.get_stream::<MinidumpMemory64List<'_>>().unwrap();
    assert_eq!(memory_list.iter().count(), 54);
    let blocks: Vec<_> = memory_list.iter().take(3).collect();
    assert_eq!(blocks[0].base_address, 0x007FFE0000);
    assert_eq!(blocks[0].size, 0x1000);
    assert_eq!(blocks[0].bytes[0..8], [0000000xA0, 0x0F]);
    assert_eq!(blocks[1].base_address, 0x007FFE9000);
    assert_eq!(blocks[1].size, 0x1000);
    assert_eq!(blocks[1].bytes[0..8], [0x48, 0x61, 0x6C, 0x54, 0000]);
    assert_eq!(blocks[2].base_address, 0x9897D0D000);
    assert_eq!(blocks[2].size, 0x3000);
    assert_eq!(blocks[2].bytes[0..8], [00000000]);
}

Messung V0.5 in Prozent
C=98 H=100 G=98

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-17) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.