| 74 | |
| 75 | |
| 76 | void DSCTriageView::loadImagesWithAddr(const std::vector<uint64_t>& addresses, bool includeDependencies) { |
| 77 | auto controller = SharedCacheController::GetController(*m_data); |
| 78 | if (!controller) |
| 79 | return; |
| 80 | |
| 81 | // TODO: NOTE ABOUT `IsImageLoaded` BEING COMMENTED OUT. PLEASE READ. |
| 82 | // TODO: Because commiting undo actions will use main thread to synchronize we must not be holding any locks |
| 83 | // TODO: This can really only ever be removed if: |
| 84 | // TODO: 1. we can set a user function type without creating an undo action, basically like the rest of shared cache |
| 85 | // TODo: use an auto function or some hack to get the user function but without the undo action. |
| 86 | // TODO: 2. we can use the undo buffer from any thread and not just the main thread |
| 87 | // TODO: I have exhausted all other options, this is a serious issue we should address soon. |
| 88 | typedef std::vector<CacheImage> ImageList; |
| 89 | ImageList images = {}; |
| 90 | for (const uint64_t& addr : addresses) |
| 91 | { |
| 92 | auto image = controller->GetImageContaining(addr); |
| 93 | if (image.has_value()) |
| 94 | { |
| 95 | // Only try to load if we have not already. |
| 96 | // if (!controller->IsImageLoaded(*image)) |
| 97 | images.emplace_back(*image); |
| 98 | |
| 99 | // TODO: We currently only add direct dependencies, may want to make the depth configurable? |
| 100 | if (includeDependencies) |
| 101 | { |
| 102 | auto dependencies = controller->GetImageDependencies(*image); |
| 103 | for (const auto& depName : dependencies) |
| 104 | { |
| 105 | auto depImage = controller->GetImageWithName(depName); |
| 106 | if (depImage.has_value()/* && !controller->IsImageLoaded(*depImage) */) |
| 107 | { |
| 108 | images.emplace_back(*depImage); |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | } |
| 114 | |
| 115 | // Don't create a worker action if we don't have any images. |
| 116 | if (images.empty()) |
| 117 | return; |
| 118 | Ref<BackgroundTask> imageLoadTask = new BackgroundTask("Loading images...", true); |
| 119 | |
| 120 | // Apply the images in a future than update the triage view and run analysis. |
| 121 | QPointer<QFutureWatcher<ImageList>> watcher = new QFutureWatcher<ImageList>(this); |
| 122 | connect(watcher, &QFutureWatcher<ImageList>::finished, this, [watcher, this]() { |
| 123 | if (watcher) |
| 124 | { |
| 125 | auto loadedImages = watcher->result(); |
| 126 | if (loadedImages.empty()) |
| 127 | return; |
| 128 | |
| 129 | // Update the triage to display the images as loaded. |
| 130 | for (const auto& image : loadedImages) |
| 131 | setImageLoaded(image.headerAddress); |
| 132 | |
| 133 | // Run analysis. |
no test coverage detected