microsoft / infersharp

Infer# is an interprocedural and scalable static code analyzer for C#. Via the capabilities of Facebook's Infer, this tool detects null dereferences, resource leaks, and thread-safety violations. It also performs taint flow tracking to detect critical security vulnerabilities like SQL injections.
MIT License
727 stars 28 forks source link

WSL "Nothing to compile. Try cleaning the build first." #219

Closed crener closed 12 months ago

crener commented 1 year ago

Super excited to run infersharp on my codebase but it seems that the distro from the releases doesn't work for me.

I got WSL2 up and running, setup the latest 1.5 distro and tried to run it against my code which gave me Nothing to compile. Try cleaning the build first.. The example folder has the same result (here is the log from infer-out\logs):

[18480][      debug] Sqlite write daemon: starting up
[18480][      debug] Sqlite write daemon: set up complete, waiting for connections
[18480][environment] CWD = /root/infersharp
[18480][environment] Read configuration in /root/infersharp/.inferconfig
[18480][environment] Project root = /root/infersharp
[18480][environment] INFER_ARGS =   @/tmp/args.tmp.2b2a08 --progress-bar-style multiline
[18480][environment] command line arguments:   infer run --cfg-json infer-staging/cfg.json
[18480][environment]                           --tenv-json infer-staging/tenv.json
[18480][environment] Could not retrieve available memory (possibly not on Linux)
[18480][environment] Active checkers: self-in-block (C/C++/ObjC), parameter-not-null-checked (C/C++/ObjC), starvation (C/C++/ObjC, Java), siof (C/C++/ObjC), racerd (C/C++/ObjC, C#/.Net, Java), pulse (C/C++/ObjC, C#/.Net, Erlang, Hack, Java), liveness (C/C++/ObjC), inefficient-keyset-iterator (Java), fragment-retains-view (Java)
[18480][environment] Scheduler: file
[18480][environment] Cores used: 10
[18480][environment] Infer version v1.1.0-9d469330b6
[18480][environment] Copyright 2009 - present Facebook. All Rights Reserved.
[18480][environment] 
[18480][   progress] Capturing using JSON mode...
[18480][      debug] Tenv.store: global tenv has size 92646776 bytes.
[18480][      debug] Tenv.store: canonicalized tenv has size 77879600 bytes.
[18480][      debug] GC stats for capture:
[18480][      debug]   minor_words: 9.76167e+07
[18480][      debug]   promoted_words: 3.50925e+07
[18480][      debug]   major_words: 3.58421e+07
[18480][      debug]   minor_collections: 97
[18480][      debug]   major_collections: 7
[18480][      debug]   compactions: 0
[18480][      debug]   top_heap_words: 38164992
[18480][      debug]   
[18480][  user warn] Nothing to compile. Try cleaning the build first.
[18480][   progress] There was nothing to analyze.
[18480][      debug] GC stats for report:
[18480][      debug]   minor_words: 3977
[18480][      debug]   promoted_words: 0
[18480][      debug]   major_words: 0
[18480][      debug]   minor_collections: 0
[18480][      debug]   major_collections: 0
[18480][      debug]   compactions: 0
[18480][      debug]   top_heap_words: 38164992
[18480][      debug]   
[18480][      debug] GC stats for main_process_full:
[18480][      debug]   minor_words: 1.00486e+08
[18480][      debug]   promoted_words: 3.54107e+07
[18480][      debug]   major_words: 3.61951e+07
[18480][      debug]   minor_collections: 104
[18480][      debug]   major_collections: 7
[18480][      debug]   compactions: 0
[18480][      debug]   top_heap_words: 38164992
[18480][      debug]   
[18481][      debug] Detected 0 spec overwrittes.
[18481][      debug] Sqlite write daemon: terminating
[18480][     result] 
  No issues found  

I saw that a very similar issue was raised here https://github.com/microsoft/infersharp/issues/213, Following the advice there I removed infer-out and infer-staging but got the same result when running either my code or the provided examples.

The staging folder also looks correct image

Is there more verbose logging that I can enable to narrow down the issue? or something that I can change locally so that it works in WSL?

matjin commented 1 year ago

Still trying to look into this issue. Thanks for raising it!

crener commented 1 year ago

@matjin is there anything I can do to help you diagnose the issue?

matjin commented 1 year ago

Can you zip up your WSL distribution for which this is an issue, upload it to some online storage, and then give me a link? I'll try to import it on a fresh machine and see if I can reproduce the issue.

I have attempted to observe this issue on a fresh machine with the current 1.5 distro, but haven't been able to. I suspect it has something specific to do with the machine, but at least this way I can confirm that it's the machine not the distro.

crener commented 1 year ago

I mean that image doesn't have anything special, it's literally the one from Github with no customisation.

Is there maybe some parameter I can give to output more diagnostic information so that I can narrow down the area the issue is in?

matjin commented 1 year ago

Two things to look into:

  1. From within the infer-staging directory in your WSL infersharp1.5 distribution, can you run "infer run --cfg-json cfg.json --tenv-json tenv.json", additionally adding either of the following arguments: "--project root /" or "--backtrack-level 1000" ? This should force Infer to run independently of the locations of the source files.
  2. Can you confirm that the filenames of the source files in cfg.json are within the project root?
crener commented 1 year ago

Ok, I've ran those commands on the example project:

With the project output it's:

:~/infersharp/infer-staging# infer run --cfg-json cfg.json --tenv-json tenv.json --project-root /
Capturing using JSON mode...
Nothing to compile. Try cleaning the build first.
There was nothing to analyze.

The other backtrack command has the same error:

:~/infersharp/infer-staging# infer run --cfg-json cfg.json --tenv-json tenv.json --backtrack-level 1000
Capturing using JSON mode...
Nothing to compile. Try cleaning the build first.
There was nothing to analyze.

The second point: Looking through the cfg.txt file it seems like there is example code there. I'm seeing namespaces that are related to the code here InferResourceLeakTests, subproj.WeatherForecast, PulseTaintTests and so on. So I think the transition is doing it's job correctly.

I've put it here just in case there is something that your expecting that I haven't noticed (This is the example project) cfg.txt

I had another comment earlier but that was mentioning an error but that was because I had cleaned out the folder and there was no tenv.json file. I fixed that and now the infer output looks quite normal again, sorry for the spam.

matjin commented 12 months ago

Can you provide the cfg.json file? The cfg.txt doesn't contain the paths in question.

crener commented 12 months ago

Here you go: cfg.json.txt

I had to change the extension to be a txt in order to upload

matjin commented 12 months ago

OK I have an idea on what is going on here. Looking back at your screenshot, looks like you are running off of a "Network" directory:

image

It looks like your paths are coming out incorrectly, since the part of the Infer# pipeline that converts an absolute path into a relative one is conditional on finding a ":" indicating a drive -- I take that you don't actually have one?

image

Anyway, a side-by-side comparison of your sourcefile path and mine reinforces the discrepancy between sourcefile paths which is likely the root cause of this issue:

image

To summarize: Can you confirm what the format of your filepaths is? In particular, do they contain the ":"?

crener commented 12 months ago

That network directory is for windows explorer to access the linux drive, you can replicate this by going to the infersharp folder and entering Explorer.exe . into the linux shell (the dot is important otherwise it won't do the navigation)

When I run infer-sharp it's done via command line (cmd not powershell) and I enter via the wsl command. Then do the actual running of infer-sharp in there (via ./run-infer.sh Examples/) which runs the provided example directory in the linux shell, I presume that has the normal linux path (as it's directly next to the sh file).

In the comment from the other day about running in the infer-staging directory I pasted in the full text and before that was my pc name, so :~/infersharp/infer-staging is actually PC:~/infersharp/infer-staging I think the :~ is just to separate from the username/computer name?

As far as I know it's running locally from the PC from the storage on the computer directly, at least I didn't have an exotic install process or anything like that.

When I'm back at that PC in a few hours I'll see about pointing it at something on another drive but as far as I could tell in wsl the system drives are just /mnt/c/.... so there wouldn't be a : in there either right? as that's still a linux based path? Is there a way to get a windows style C:\users\user\sourceDir\... into there (I haven't tried that yet) that the infer-sharp code is expecting? because if that is the intended way to use this I've been going through mnt or copying the dlls into a folder next to the infer script which might explain the confusion.

I'll try some stuff when I'm back at the PC and see what happens

matjin commented 12 months ago

Scratch that -- I'm actually able to reproduce the exact same filepath myself on the WSL distro, and the analysis works just fine in that situation. I think there might be something specific to WSL, because of the discrepancy in the logs which says Infer couldn't retrieve available memory:

image

I noticed also this is in common with the other issue that you cited in your initial post.

Are you on wsl version 2? For example, this is what I get from wsl -l -v:

image

crener commented 12 months ago

Ahhhh yeah I have WSL 2 installed as far as I know but for some reason it's using 1 image

crener commented 12 months ago

Ok, so doing wsl --set-version infersharp1.5 2 has switched it to WSL 2 and now it works.

I feel like getting people to check the logs for that memory warning or checking it's using WSL 2 with the wsl -l -v command would be a good thing to add to the https://github.com/microsoft/infersharp/blob/main/TROUBLESHOOTING.md page

matjin commented 12 months ago

Great! Happy to hear this fixed it :)

And thank you for working this out! I will modify the documentation.

crener commented 12 months ago

Thanks for being patent with me :)