periphery icon indicating copy to clipboard operation
periphery copied to clipboard

Periphery doesn't work as expected when `skip_build: true` and `index_store_path` specified

Open subdan opened this issue 4 years ago • 5 comments

Hello.

I want to run Periphery on CI after the unit-tests passed. Right now I run Periphery with skip_build: false and index_store_path: null. This works as expected. But I want to increase speed of periphery scan by setting skip_build: true and specify index_store_path. When I'm doing this Periphery doesn't work. It outputs a lot of false positives.

When index_store_path is null I see a lot of [index:swift] PATH_TO_SWIFT_FILE lines in the output. This is good.

When index_store_path is not null I see a lot of the following lines in the output. [index:swift] Failed to identify property declaration at PATH_TO_SWIFT_FILE [index:swift] Failed to identify conformable declaration at PATH_TO_SWIFT_FILE [index:swift] Failed to identify function declaration at at PATH_TO_SWIFT_FILE

Before running periphery scan I press CMD+B in the Xcode to build my app and wait until it finishes.

Why Periphery perform an indexing phase with a lot of errors when skip_build: true and index_store_path specified?

subdan avatar Jan 28 '22 11:01 subdan

I've removed Derived Data directory and now everything works as expected. When running xcodebuild ... clean it doesn't remove contents of the Index directory. I noticed that Index directory may contains "bad" files that seems to breaks Periphery.

Example: In the .../Index/DataStore/v5/units/ directory I have MainScreen.o-3Q052XDC7WQ3W file.

Sometimes I see several Main.screen.o-HASH files with different HASH. It is an LLVM Hash of the absolute path of the output file.

When a file is moved to the different location LLVM Hash recalculated and we have several files in the units directory.

When I remove any file, *.o-Hash file is still exists.

subdan avatar Feb 01 '22 07:02 subdan

Right now I have two unit files:

image

I've add a breakpoint to the SwiftIndexer:51 with condition = unit.name?.contains("TransferRouter") == true

Both of the files links to the same file:

(lldb) po unit.name
▿ Optional<String>
  - some : "TransferRouter.o-RKWE3OGIRH93"

(lldb) po filePath
".../Transfer/TransferRouter.swift"

(lldb) po unit.name
▿ Optional<String>
  - some : "TransferRouter.o-BDYR936CXPMC"

(lldb) po filePath
".../Transfer/TransferRouter.swift"

Periphery uses incorrect unit file which causes a false positives.

subdan avatar Feb 01 '22 10:02 subdan

How Periphery can decide which unit file to use:

  1. Compare by modified date and use newest file.
  2. Check target of unit file. target can be arm or x86_64. I am on the M1 Mac so Periphery must use unit file with arm target.

subdan avatar Feb 02 '22 10:02 subdan

Hey @subdan, sorry for such a late reply on this. Did you manage to get any further? Is the issue that the index store path to the source file is incorrect for the old unit, or that the arch is different?

ileitch avatar Apr 15 '22 18:04 ileitch

Hi, @ileitch. We run Periphery on a CI machine. We noticed that sometimes Periphery doesn't work as expected and shows some false positives. We happened to discover that when we keep open Xcode on CI machine it breaks Index/DataStore. Unit and record files gets duplicated as I mention earlier. Periphery uses wrong unit and record files and shows false positives.

We cleaned up Index directory and decided to never open Xcode on CI machine. This fixed the issue.

Now, we have the following flow that works as expected with Periphery:

  1. Run build for testing — Faslane scan action with build_for_testing: true
  2. Run tests — Faslane scan action with test_without_building: true
  3. Run Periphery with skip_build: true and --index-store-path flags

subdan avatar Apr 15 '22 19:04 subdan

Thanks for investigating the root cause. I've added a check to detect these conflicting units.

ileitch avatar Nov 20 '22 16:11 ileitch