diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e98cf86de..234601424 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: run: pip install --upgrade black flake8 - name: Run Black - run: black --check tests + run: black --check --diff tests - name: Run Flake8 run: flake8 tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 50a45d075..3b497f13d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- Symbolication responses include download information about all DIF object files which were looked up on the available object sources. ([#309](https://github.com/getsentry/symbolicator/pull/309)) +- Symbolication responses include download information about all DIF object files which were looked up on the available object sources. ([#309](https://github.com/getsentry/symbolicator/pull/309) [#316](https://github.com/getsentry/symbolicator/pull/316)) ### Bug Fixes diff --git a/src/actors/objects/mod.rs b/src/actors/objects/mod.rs index 9948925ee..6886f2a27 100644 --- a/src/actors/objects/mod.rs +++ b/src/actors/objects/mod.rs @@ -21,7 +21,9 @@ use crate::cache::{Cache, CacheKey, CacheStatus}; use crate::logging::LogError; use crate::services::download::{DownloadError, DownloadService, DownloadStatus}; use crate::sources::{FileType, SourceConfig, SourceFileId, SourceId, SourceLocation}; -use crate::types::{ObjectCandidate, ObjectDownloadInfo, ObjectFeatures, ObjectId, Scope}; +use crate::types::{ + AllObjectCandidates, ObjectCandidate, ObjectDownloadInfo, ObjectFeatures, ObjectId, Scope, +}; use crate::utils::futures::ThreadPool; use crate::utils::sentry::{SentryFutureExt, WriteSentryScope}; @@ -421,6 +423,18 @@ impl ObjectFileMeta { pub fn features(&self) -> ObjectFeatures { self.features } + + pub fn source(&self) -> &SourceId { + self.request.file_id.source_id() + } + + pub fn location(&self) -> SourceLocation { + self.request.file_id.location() + } + + pub fn status(&self) -> CacheStatus { + self.status + } } /// Handle to local cache file of an object. @@ -544,7 +558,7 @@ pub struct FoundObject { pub meta: Option>, /// This is a list of some meta information on all objects which have been considered /// for this object. It could be populated even if no matching object is found. - pub candidates: Vec, + pub candidates: AllObjectCandidates, } impl ObjectsActor { @@ -736,7 +750,7 @@ impl ObjectsActor { }) .map(|(_i, response)| response) .transpose() - .map(|meta| FoundObject { meta, candidates }) + .map(|meta| FoundObject { meta, candidates: candidates.into() }) }, ) } diff --git a/src/actors/snapshots/symbolicator__actors__symbolication__tests__add_bucket-2.snap b/src/actors/snapshots/symbolicator__actors__symbolication__tests__add_bucket-2.snap index 8059d85ae..72d3b44f8 100644 --- a/src/actors/snapshots/symbolicator__actors__symbolication__tests__add_bucket-2.snap +++ b/src/actors/snapshots/symbolicator__actors__symbolication__tests__add_bucket-2.snap @@ -38,6 +38,8 @@ modules: has_unwind_info: false has_symbols: true has_sources: false + debug: + status: ok - source: local location: 502F/C0A5/1EC1/3E47/9998/684FA139DCA7.app download: diff --git a/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_linux.snap b/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_linux.snap index 99ee40ea8..f5e255318 100644 --- a/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_linux.snap +++ b/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_linux.snap @@ -143,7 +143,7 @@ modules: image_size: 106496 candidates: - source: local - location: f1/c3bcc0279865fe3058404b2831d9e64135386c.debug + location: crash/C0BCC3F19827FE653058404B2831D9E60/crash.sym download: status: notfound - source: local @@ -151,7 +151,7 @@ modules: download: status: notfound - source: local - location: crash/C0BCC3F19827FE653058404B2831D9E60/crash.sym + location: f1/c3bcc0279865fe3058404b2831d9e64135386c.debug download: status: notfound - debug_status: unused @@ -186,11 +186,11 @@ modules: image_size: 1835008 candidates: - source: local - location: b5/381a457906d279073822a5ceb24c4bfef94ddb.debug + location: b5/381a457906d279073822a5ceb24c4bfef94ddb download: status: notfound - source: local - location: b5/381a457906d279073822a5ceb24c4bfef94ddb + location: b5/381a457906d279073822a5ceb24c4bfef94ddb.debug download: status: notfound - source: local @@ -259,11 +259,11 @@ modules: image_size: 155648 candidates: - source: local - location: 5d/7b6259552275a3c17bd4c3fd05f5a6bf40caa5.debug + location: 5d/7b6259552275a3c17bd4c3fd05f5a6bf40caa5 download: status: notfound - source: local - location: 5d/7b6259552275a3c17bd4c3fd05f5a6bf40caa5 + location: 5d/7b6259552275a3c17bd4c3fd05f5a6bf40caa5.debug download: status: notfound - source: local @@ -287,11 +287,11 @@ modules: image_size: 8192 candidates: - source: local - location: 6c/5f1875b9048fb4b8dfd832e74ad31a9aafb38f.debug + location: 6c/5f1875b9048fb4b8dfd832e74ad31a9aafb38f download: status: notfound - source: local - location: 6c/5f1875b9048fb4b8dfd832e74ad31a9aafb38f + location: 6c/5f1875b9048fb4b8dfd832e74ad31a9aafb38f.debug download: status: notfound - source: local diff --git a/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_windows.snap b/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_windows.snap index 392a28c8a..7c34e5be6 100644 --- a/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_windows.snap +++ b/src/actors/snapshots/symbolicator__actors__symbolication__tests__minidump_windows.snap @@ -170,16 +170,7 @@ modules: image_size: 36864 candidates: - source: local - location: crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pdb - download: - status: ok - features: - has_debug_info: true - has_unwind_info: true - has_symbols: true - has_sources: false - - source: local - location: crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pd_ + location: crash.exe/5AB380779000/crash.ex_ download: status: notfound - source: local @@ -187,9 +178,20 @@ modules: download: status: notfound - source: local - location: crash.exe/5AB380779000/crash.ex_ + location: crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pd_ download: status: notfound + - source: local + location: crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pdb + download: + status: ok + features: + has_debug_info: true + has_unwind_info: true + has_symbols: true + has_sources: false + debug: + status: ok - source: local location: crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.sym download: @@ -361,19 +363,19 @@ modules: image_size: 917504 candidates: - source: local - location: wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pdb + location: kernel32.dll/590285E9e0000/kernel32.dl_ download: status: notfound - source: local - location: wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pd_ + location: kernel32.dll/590285E9e0000/kernel32.dll download: status: notfound - source: local - location: kernel32.dll/590285E9e0000/kernel32.dll + location: wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pd_ download: status: notfound - source: local - location: kernel32.dll/590285E9e0000/kernel32.dl_ + location: wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pdb download: status: notfound - source: local @@ -457,19 +459,19 @@ modules: image_size: 1585152 candidates: - source: local - location: wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pdb + location: ntdll.dll/59B0D8F3183000/ntdll.dl_ download: status: notfound - source: local - location: wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pd_ + location: ntdll.dll/59B0D8F3183000/ntdll.dll download: status: notfound - source: local - location: ntdll.dll/59B0D8F3183000/ntdll.dll + location: wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pd_ download: status: notfound - source: local - location: ntdll.dll/59B0D8F3183000/ntdll.dl_ + location: wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pdb download: status: notfound - source: local diff --git a/src/actors/snapshots/symbolicator__actors__symbolication__tests__remove_bucket.snap b/src/actors/snapshots/symbolicator__actors__symbolication__tests__remove_bucket.snap index 8059d85ae..72d3b44f8 100644 --- a/src/actors/snapshots/symbolicator__actors__symbolication__tests__remove_bucket.snap +++ b/src/actors/snapshots/symbolicator__actors__symbolication__tests__remove_bucket.snap @@ -38,6 +38,8 @@ modules: has_unwind_info: false has_symbols: true has_sources: false + debug: + status: ok - source: local location: 502F/C0A5/1EC1/3E47/9998/684FA139DCA7.app download: diff --git a/src/actors/symbolication.rs b/src/actors/symbolication.rs index 68fbfa3c2..160a572d7 100644 --- a/src/actors/symbolication.rs +++ b/src/actors/symbolication.rs @@ -673,9 +673,7 @@ impl SymCacheLookup { entry.object_info.arch = symcache.arch(); entry.object_info.features.merge(symcache.features()); - let mut difs = Vec::new(); - difs.extend_from_slice(&symcache.candidates()); - entry.object_info.candidates = difs; // TODO(flub): merge! + entry.object_info.candidates = symcache.candidates(); // TODO(flub): merge! } entry.symcache = symcache; diff --git a/src/actors/symcaches.rs b/src/actors/symcaches.rs index dec5addce..ed67be04d 100644 --- a/src/actors/symcaches.rs +++ b/src/actors/symcaches.rs @@ -17,7 +17,9 @@ use crate::actors::objects::{ }; use crate::cache::{Cache, CacheKey, CacheStatus}; use crate::sources::{FileType, SourceConfig}; -use crate::types::{ObjectCandidate, ObjectFeatures, ObjectId, ObjectType, Scope}; +use crate::types::{ + AllObjectCandidates, ObjectFeatures, ObjectId, ObjectType, ObjectUseInfo, Scope, +}; use crate::utils::futures::ThreadPool; use crate::utils::sentry::{SentryFutureExt, WriteSentryScope}; @@ -75,7 +77,7 @@ pub struct SymCacheFile { features: ObjectFeatures, status: CacheStatus, arch: Arch, - candidates: Arc<[ObjectCandidate]>, + candidates: AllObjectCandidates, } impl SymCacheFile { @@ -100,7 +102,7 @@ impl SymCacheFile { } /// Returns the list of DIFs which were searched for this symcache. - pub fn candidates(&self) -> Arc<[ObjectCandidate]> { + pub fn candidates(&self) -> AllObjectCandidates { self.candidates.clone() } } @@ -111,7 +113,7 @@ struct FetchSymCacheInternal { objects_actor: ObjectsActor, object_meta: Arc, threadpool: ThreadPool, - candidates: Arc<[ObjectCandidate]>, + candidates: AllObjectCandidates, } impl CacheItemRequest for FetchSymCacheInternal { @@ -184,6 +186,31 @@ impl CacheItemRequest for FetchSymCacheInternal { .map(|cache| cache.arch()) .unwrap_or_default(); + // If self.object_meta.status() was != Positive than that status got passed straight + // through to our own `status` argument. + let debug = match status { + CacheStatus::Positive => ObjectUseInfo::Ok, + CacheStatus::Negative => { + if self.object_meta.status() == CacheStatus::Positive { + ObjectUseInfo::Error { + details: String::from("Object file no longer available"), + } + } else { + // No need to pretend that we were going to use this symcache if the + // original object file was already not there, that status is already + // reported. + ObjectUseInfo::None + } + } + CacheStatus::Malformed => ObjectUseInfo::Malformed, + }; + let mut candidates = self.candidates.clone(); // yuk! + candidates.set_debug( + self.object_meta.source().clone(), + self.object_meta.location(), + debug, + ); + SymCacheFile { object_type: self.request.object_type, identifier: self.request.identifier.clone(), @@ -192,7 +219,7 @@ impl CacheItemRequest for FetchSymCacheInternal { features: self.object_meta.features(), status, arch, - candidates: self.candidates.clone(), + candidates, } } } @@ -232,7 +259,6 @@ impl SymCacheActor { find_result_future.and_then(move |find_result: FoundObject| { let FoundObject { meta, candidates } = find_result; - let candidates: Arc<[ObjectCandidate]> = Arc::from(candidates); meta.map(clone!(candidates, |object_meta| { Either::A(symcaches.compute_memoized(FetchSymCacheInternal { request, diff --git a/src/sources.rs b/src/sources.rs index 66973c771..f49848a17 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -15,7 +15,7 @@ use crate::utils::sentry::WriteSentryScope; /// An identifier for DIF sources. /// /// This is essentially a newtype for a string. -#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub struct SourceId(String); // For now we allow this to be unused, some tests use these already. @@ -103,7 +103,7 @@ impl WriteSentryScope for SourceConfig { /// /// It is essentially a `/`-separated string. This is currently used by all sources other than /// [`SentrySourceConfig`]. This may change in the future. -#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub struct SourceLocation(String); impl SourceLocation { diff --git a/src/types.rs b/src/types/mod.rs similarity index 96% rename from src/types.rs rename to src/types/mod.rs index 89e53fc35..28bc2b4ac 100644 --- a/src/types.rs +++ b/src/types/mod.rs @@ -3,8 +3,13 @@ //! This module contains all the types which (de)serialise to/from JSON to make up the //! public HTTP API. //! -//! Or at least it strives to. Currently it also contains some extra common types as well -//! some types for the public API exist in other places. Feel free to fix this up. +//! Some types also require `impl` blocks, these live in a sub-module so that the `mod.rs` +//! file contains only type definitions which are part of the JSON schema. +//! +//! Or at least this is what is the desired state. Currently it also contains some extra +//! common types as well some types for the public API exist in other places. There are +//! also a number of `impl`s which have not yet been moved to a sub-module. Feel free to +//! fix this up. use std::borrow::Cow; use std::collections::BTreeMap; @@ -25,6 +30,8 @@ use crate::utils::addr::AddrMode; use crate::utils::hex::HexValue; use crate::utils::sentry::WriteSentryScope; +mod objects; + /// Symbolication task identifier. #[derive(Debug, Clone, Copy, Serialize, Ord, PartialOrd, Eq, PartialEq)] pub struct RequestId(Uuid); @@ -572,17 +579,13 @@ pub enum ObjectUseInfo { None, } -impl Default for ObjectUseInfo { - fn default() -> Self { - Self::None - } -} - -impl ObjectUseInfo { - pub fn is_none(&self) -> bool { - matches!(self, Self::None) - } -} +/// Newtype around a collection of [`ObjectCandidate`] structs. +/// +/// This abstracts away some common operations needed on this collection. +/// +/// [`CacheItemRequest`]: ../actors/common/cache/trait.CacheItemRequest.html +#[derive(Clone, Debug, Default, Serialize, Deserialize, Eq, PartialEq)] +pub struct AllObjectCandidates(Vec); /// Normalized [`RawObjectInfo`] with status attached. /// @@ -618,8 +621,8 @@ pub struct CompleteObjectInfo { /// reasons. /// /// This list is not serialised if it is empty. - #[serde(skip_serializing_if = "Vec::is_empty", default)] - pub candidates: Vec, + #[serde(skip_serializing_if = "AllObjectCandidates::is_empty", default)] + pub candidates: AllObjectCandidates, } impl CompleteObjectInfo { @@ -654,31 +657,6 @@ impl CompleteObjectInfo { } } -impl From for CompleteObjectInfo { - fn from(mut raw: RawObjectInfo) -> Self { - raw.debug_id = raw - .debug_id - .filter(|id| !id.is_empty()) - .and_then(|id| id.parse::().ok()) - .map(|id| id.to_string()); - - raw.code_id = raw - .code_id - .filter(|id| !id.is_empty()) - .and_then(|id| id.parse::().ok()) - .map(|id| id.to_string()); - - CompleteObjectInfo { - debug_status: ObjectFileStatus::Unused, - unwind_status: None, - features: ObjectFeatures::default(), - arch: Arch::Unknown, - raw, - candidates: Vec::new(), - } - } -} - /// The response of a symbolication request or poll request. #[derive(Debug, Clone, Serialize)] #[serde(tag = "status", rename_all = "snake_case")] diff --git a/src/types/objects.rs b/src/types/objects.rs new file mode 100644 index 000000000..b6af70db8 --- /dev/null +++ b/src/types/objects.rs @@ -0,0 +1,88 @@ +//! Implementations for the types describing DIF object files. + +use super::{ + AllObjectCandidates, Arch, CodeId, CompleteObjectInfo, DebugId, ObjectCandidate, + ObjectFeatures, ObjectFileStatus, ObjectUseInfo, RawObjectInfo, +}; +use crate::sources::{SourceId, SourceLocation}; + +impl Default for ObjectUseInfo { + fn default() -> Self { + Self::None + } +} + +impl ObjectUseInfo { + pub fn is_none(&self) -> bool { + matches!(self, Self::None) + } +} + +impl From> for AllObjectCandidates { + fn from(mut source: Vec) -> Self { + source + .sort_by_cached_key(|candidate| (candidate.source.clone(), candidate.location.clone())); + Self(source) + } +} + +impl AllObjectCandidates { + /// Sets the [`ObjectCandidate::debug`] field for the specified DIF object. + /// + /// You can only request symcaches from a DIF object that was already in the metadata + /// candidate list, therefore if the candidate is missing it is treated as an error. + pub fn set_debug(&mut self, source: SourceId, location: SourceLocation, info: ObjectUseInfo) { + match self + .0 + .binary_search_by_key(&(source, location), |candidate| { + (candidate.source.clone(), candidate.location.clone()) + }) { + Ok(index) => { + if let Some(mut candidate) = self.0.get_mut(index) { + candidate.debug = info; + } + } + Err(_) => { + sentry::capture_message( + "Missing ObjectCandidate in AllObjectCandidates::set_debug", + sentry::Level::Error, + ); + } + } + } + + /// Returns `true` if the collections contains no [`ObjectCandidate`]s. + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } + + /// Removes all DIF object from this candidates collection. + pub fn clear(&mut self) { + self.0.clear() + } +} + +impl From for CompleteObjectInfo { + fn from(mut raw: RawObjectInfo) -> Self { + raw.debug_id = raw + .debug_id + .filter(|id| !id.is_empty()) + .and_then(|id| id.parse::().ok()) + .map(|id| id.to_string()); + + raw.code_id = raw + .code_id + .filter(|id| !id.is_empty()) + .and_then(|id| id.parse::().ok()) + .map(|id| id.to_string()); + + CompleteObjectInfo { + debug_status: ObjectFileStatus::Unused, + unwind_status: None, + features: ObjectFeatures::default(), + arch: Arch::Unknown, + raw, + candidates: AllObjectCandidates::default(), + } + } +} diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 72d310d5d..d78439fd7 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -207,10 +207,7 @@ def _handle_path(path, start_response): filename = os.path.join( os.path.dirname(__file__), "..", "fixtures", "symbols", path ) - with open( - filename, - "rb", - ) as f: + with open(filename, "rb") as f: d = f.read() start_response("200 OK", [("Content-Length", str(len(d)))]) return [d] diff --git a/tests/integration/test_basic.py b/tests/integration/test_basic.py index 16ab992b4..d407a9def 100644 --- a/tests/integration/test_basic.py +++ b/tests/integration/test_basic.py @@ -61,6 +61,12 @@ "image_size": 851_968, "candidates": [ { + "download": {"status": "notfound"}, + "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pd_", + "source": "microsoft", + }, + { + "debug": {"status": "ok"}, "download": { "features": { "has_debug_info": True, @@ -73,11 +79,6 @@ "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pdb", "source": "microsoft", }, - { - "download": {"status": "notfound"}, - "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pd_", - "source": "microsoft", - }, ], } ], @@ -124,12 +125,12 @@ def _make_unsuccessful_result(status, source="microsoft"): response["modules"][0]["candidates"] = [ { "download": {"status": "notfound"}, - "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pdb", + "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pd_", "source": source, }, { "download": {"status": "notfound"}, - "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pd_", + "location": "wkernel32.pdb/FF9F9F7841DB88F0CDEDA9E1E9BFF3B51/wkernel32.pdb", "source": source, }, ] diff --git a/tests/integration/test_gcs.py b/tests/integration/test_gcs.py index 1e1c78624..34306327c 100644 --- a/tests/integration/test_gcs.py +++ b/tests/integration/test_gcs.py @@ -57,13 +57,17 @@ }, "candidates": [ { - "download": { - "status": "notfound", - }, + "download": {"status": "notfound"}, + "location": "e5/14c9464eed3be5943a2c61d9241fad/breakpad", + "source": "ios", + }, + { + "download": {"status": "notfound"}, "location": "e5/14c9464eed3be5943a2c61d9241fad/debuginfo", "source": "ios", }, { + "debug": {"status": "ok"}, "download": { "features": { "has_debug_info": False, @@ -76,13 +80,6 @@ "location": "e5/14c9464eed3be5943a2c61d9241fad/executable", "source": "ios", }, - { - "download": { - "status": "notfound", - }, - "location": "e5/14c9464eed3be5943a2c61d9241fad/breakpad", - "source": "ios", - }, ], }, { @@ -101,13 +98,17 @@ }, "candidates": [ { - "download": { - "status": "notfound", - }, + "download": {"status": "notfound"}, + "location": "71/9044f95fe23ee0ab14504def42b100/breakpad", + "source": "ios", + }, + { + "download": {"status": "notfound"}, "location": "71/9044f95fe23ee0ab14504def42b100/debuginfo", "source": "ios", }, { + "debug": {"status": "ok"}, "download": { "features": { "has_debug_info": False, @@ -120,13 +121,6 @@ "location": "71/9044f95fe23ee0ab14504def42b100/executable", "source": "ios", }, - { - "download": { - "status": "notfound", - }, - "location": "71/9044f95fe23ee0ab14504def42b100/breakpad", - "source": "ios", - }, ], }, ], diff --git a/tests/integration/test_minidump.py b/tests/integration/test_minidump.py index 3cce94789..5f433a6ed 100644 --- a/tests/integration/test_minidump.py +++ b/tests/integration/test_minidump.py @@ -334,22 +334,22 @@ "candidates": [ { "source": "microsoft", - "location": "crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pdb", + "location": "crash.exe/5AB380779000/crash.ex_", "download": {"status": "notfound"}, }, { "source": "microsoft", - "location": "crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pd_", + "location": "crash.exe/5AB380779000/crash.exe", "download": {"status": "notfound"}, }, { "source": "microsoft", - "location": "crash.exe/5AB380779000/crash.exe", + "location": "crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pd_", "download": {"status": "notfound"}, }, { "source": "microsoft", - "location": "crash.exe/5AB380779000/crash.ex_", + "location": "crash.pdb/3249D99D0C4049318610F4E4FB0B69361/crash.pdb", "download": {"status": "notfound"}, }, ], @@ -372,17 +372,22 @@ "unwind_status": "unused", "type": "pe", "candidates": [ + { + "download": {"status": "notfound"}, + "location": "dbghelp.dll/57898E12145000/dbghelp.dl_", + "source": "microsoft", + }, { "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, - "location": "dbghelp.pdb/9C2A902B6FDF40AD8308588A41D572A01/dbghelp.pdb", + "location": "dbghelp.dll/57898E12145000/dbghelp.dll", "source": "microsoft", }, { @@ -391,21 +396,17 @@ "source": "microsoft", }, { + "debug": {"status": "ok"}, "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - "location": "dbghelp.dll/57898E12145000/dbghelp.dll", - "source": "microsoft", - }, - { - "download": {"status": "notfound"}, - "location": "dbghelp.dll/57898E12145000/dbghelp.dl_", + "location": "dbghelp.pdb/9C2A902B6FDF40AD8308588A41D572A01/dbghelp.pdb", "source": "microsoft", }, ], @@ -464,17 +465,22 @@ "image_addr": "0x70b70000", "image_size": 151_552, "candidates": [ + { + "download": {"status": "notfound"}, + "location": "dbgcore.dll/57898DAB25000/dbgcore.dl_", + "source": "microsoft", + }, { "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, - "location": "dbgcore.pdb/AEC7EF2FDF4B4642A4714C3E5FE8760A1/dbgcore.pdb", + "location": "dbgcore.dll/57898DAB25000/dbgcore.dll", "source": "microsoft", }, { @@ -483,21 +489,17 @@ "source": "microsoft", }, { + "debug": {"status": "ok"}, "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - "location": "dbgcore.dll/57898DAB25000/dbgcore.dll", - "source": "microsoft", - }, - { - "download": {"status": "notfound"}, - "location": "dbgcore.dll/57898DAB25000/dbgcore.dl_", + "location": "dbgcore.pdb/AEC7EF2FDF4B4642A4714C3E5FE8760A1/dbgcore.pdb", "source": "microsoft", }, ], @@ -629,17 +631,22 @@ "image_size": 917_504, "type": "pe", "candidates": [ + { + "download": {"status": "notfound"}, + "location": "kernel32.dll/590285E9e0000/kernel32.dl_", + "source": "microsoft", + }, { "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, - "location": "wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pdb", + "location": "kernel32.dll/590285E9e0000/kernel32.dll", "source": "microsoft", }, { @@ -648,21 +655,17 @@ "source": "microsoft", }, { + "debug": {"status": "ok"}, "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - "location": "kernel32.dll/590285E9e0000/kernel32.dll", - "source": "microsoft", - }, - { - "download": {"status": "notfound"}, - "location": "kernel32.dll/590285E9e0000/kernel32.dl_", + "location": "wkernel32.pdb/D347455996F747D6BF43C176B2171E681/wkernel32.pdb", "source": "microsoft", }, ], @@ -705,13 +708,18 @@ "candidates": [ { "source": "microsoft", - "location": "wrpcrt4.pdb/AE131C6727A74FA19916B5A4AEF411901/wrpcrt4.pdb", + "location": "rpcrt4.dll/5A49BB75c1000/rpcrt4.dl_", + "download": {"status": "notfound"}, + }, + { + "source": "microsoft", + "location": "rpcrt4.dll/5A49BB75c1000/rpcrt4.dll", "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, @@ -723,21 +731,17 @@ }, { "source": "microsoft", - "location": "rpcrt4.dll/5A49BB75c1000/rpcrt4.dll", + "location": "wrpcrt4.pdb/AE131C6727A74FA19916B5A4AEF411901/wrpcrt4.pdb", "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - }, - { - "source": "microsoft", - "location": "rpcrt4.dll/5A49BB75c1000/rpcrt4.dl_", - "download": {"status": "notfound"}, + "debug": {"status": "ok"}, }, ], }, @@ -779,13 +783,18 @@ "candidates": [ { "source": "microsoft", - "location": "wkernelbase.pdb/8462294AC645402DAC82A4E95F61DDF91/wkernelbase.pdb", + "location": "KERNELBASE.dll/59BF2BCF1a1000/KERNELBASE.dl_", + "download": {"status": "notfound"}, + }, + { + "source": "microsoft", + "location": "KERNELBASE.dll/59BF2BCF1a1000/KERNELBASE.dll", "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, @@ -797,21 +806,17 @@ }, { "source": "microsoft", - "location": "KERNELBASE.dll/59BF2BCF1a1000/KERNELBASE.dll", + "location": "wkernelbase.pdb/8462294AC645402DAC82A4E95F61DDF91/wkernelbase.pdb", "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - }, - { - "source": "microsoft", - "location": "KERNELBASE.dll/59BF2BCF1a1000/KERNELBASE.dl_", - "download": {"status": "notfound"}, + "debug": {"status": "ok"}, }, ], }, @@ -835,13 +840,18 @@ "candidates": [ { "source": "microsoft", - "location": "wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pdb", + "location": "ntdll.dll/59B0D8F3183000/ntdll.dl_", + "download": {"status": "notfound"}, + }, + { + "source": "microsoft", + "location": "ntdll.dll/59B0D8F3183000/ntdll.dll", "download": { "features": { - "has_debug_info": True, + "has_debug_info": False, "has_sources": False, "has_symbols": True, - "has_unwind_info": True, + "has_unwind_info": False, }, "status": "ok", }, @@ -853,21 +863,17 @@ }, { "source": "microsoft", - "location": "ntdll.dll/59B0D8F3183000/ntdll.dll", + "location": "wntdll.pdb/971F98E5CE6041FFB2D7235BBEB345781/wntdll.pdb", "download": { "features": { - "has_debug_info": False, + "has_debug_info": True, "has_sources": False, "has_symbols": True, - "has_unwind_info": False, + "has_unwind_info": True, }, "status": "ok", }, - }, - { - "source": "microsoft", - "location": "ntdll.dll/59B0D8F3183000/ntdll.dl_", - "download": {"status": "notfound"}, + "debug": {"status": "ok"}, }, ], }, diff --git a/tests/integration/test_s3.py b/tests/integration/test_s3.py index 74c56c140..1b28268ce 100644 --- a/tests/integration/test_s3.py +++ b/tests/integration/test_s3.py @@ -46,6 +46,8 @@ "type": "macho", "candidates": [ { + "source": "s3", + "location": "_.dwarf/mach-uuid-sym-502fc0a51ec13e479998684fa139dca7/_.dwarf", "download": { "features": { "has_debug_info": True, @@ -55,8 +57,7 @@ }, "status": "ok", }, - "location": "_.dwarf/mach-uuid-sym-502fc0a51ec13e479998684fa139dca7/_.dwarf", - "source": "s3", + "debug": {"status": "ok"}, }, ], } diff --git a/tests/integration/test_wasm.py b/tests/integration/test_wasm.py index 89023bed3..c98f352d7 100644 --- a/tests/integration/test_wasm.py +++ b/tests/integration/test_wasm.py @@ -2,12 +2,7 @@ "stacktraces": [ { "registers": {}, - "frames": [ - { - "instruction_addr": "0x8c", - "addr_mode": "rel:0", - } - ], + "frames": [{"instruction_addr": "0x8c", "addr_mode": "rel:0"}], }, ], "modules": [ @@ -38,6 +33,8 @@ "type": "wasm", "candidates": [ { + "source": "stuff", + "location": "bd/a18fd85d4a4eb893022d6bfad846b1.debug", "download": { "features": { "has_debug_info": True, @@ -47,8 +44,7 @@ }, "status": "ok", }, - "location": "bd/a18fd85d4a4eb893022d6bfad846b1.debug", - "source": "stuff", + "debug": {"status": "ok"}, }, ], }