Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add compiler info to result directory #1050

Merged
merged 4 commits into from
Nov 6, 2017
Merged

Conversation

martong
Copy link
Contributor

@martong martong commented Oct 17, 2017

Add the results of gcc -v like invocations as files to the result dir.
This is needed for later local investigation of any failed analysis.

Gabor Marton added 3 commits October 17, 2017 18:07
Add the results of gcc -v like invocations as files to the reult dir.
This is needed for later local investigation of any failed analysis.
Copy link
Contributor

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some high level questions and found some nits otherwise looks good.

for line in lines.splitlines(True):
line = line.strip()
if line.startswith(end_mark):
do_append = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can there be multiple occurrences of start_mark? If no, could we just break here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the original code for parsing, unfortunately diff shows this as completely new code.
Still, I think we could just break here.


return target
err = get_compiler_err(cmd)
dump_compiler_info(output_path, "compiler_target.json",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to both dump compiler info when getting the target and when getting the includes?

return target


def dump_compiler_info(output_path, filename, data):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the file already exists, we just append to it.
Is it ensured that multiple concurrent checks (to different result directories) won't interfere?
When will we clean up this file? If we don't do that, this file will just grow with subsequent checks to the same result directory.

Copy link
Contributor Author

@martong martong Oct 19, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, as we discussed I modifed the analyze.py to remove these files when starting a new analysis.

@@ -208,13 +243,13 @@ def parse_compile_commands_json(logfile, add_compiler_defaults=False):
return actions


def parse_log(logfilepath, add_compiler_defaults=False):
def parse_log(logfilepath, output_path, add_compiler_defaults=False):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think output_path worth a documentation, what this refers to.

Copy link
Contributor

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally looks good. I was wondering if it would be cleaner to have only one json file.

return target
def remove_file_if_exists(filename):
try:
os.remove(filename) # throws if file does not exsist
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We start comments with capital letters and terminate them with periods.

if os.path.exists(filename):
append_write = 'a'
with open(filename, append_write) as f:
f.write(json.dumps(data))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably this will not be a proper json in case of multiple compilers.
We have to

  • read the file first with
  • then do a json.loads on the content
  • then add the new entry
  • then write back

@martong
Copy link
Contributor Author

martong commented Oct 20, 2017

@Xazax-hun, as we discussed two files make the json handling code more compact for our benefit.

Copy link
Contributor

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! But could you squash this into two commit? One for the feature one for the test.

@whisperity whisperity added the analyzer 📈 Related to the analyze commands (analysis driver) label Oct 26, 2017
Copy link
Contributor

@whisperity whisperity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Also, commits are many.)

@@ -10,6 +10,8 @@
import traceback
import subprocess
import shlex
import json
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import order has been violated here.

"""

def get_compiler_err(cmd):
'''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

''' ➡️ """

Returns a list of default includes of the given compiler.
"""

def get_compiler_err(cmd):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, don't we have a method for arbitrary command invocation and output saving somewhere in util? Or am I mixing it up with the test library?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is util.call_command but that does not handle the stderr. Also this code is refactored from https://github.com/Ericsson/codechecker/pull/1050/files?diff=split#diff-3edc7a6cc15c42194786d15e8ab5852dL95

# where we need to strip the "(framework directory)" string.
# For instance:
# /System/Library/Frameworks (framework directory)
fpos = line.find("(framework directory)")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string::find(substr) == -1 can be replaced with substr not in string, which is more Pythonic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I agree.
Still, this is again not new code despite it looks like that in the diff; merge conflict resolution brought this in :(

return target
def remove_file_if_exists(filename):
try:
os.remove(filename) # Throws if file does not exsist.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments are unneccessary here. Also, I recall we use the following form almost everywhere in the code.

if os.path.isfile(a):  # Or exists()
  os.remove(a)

import json
# The add-compiler-defaults is a deprecated argument
# and we always perform target and include auto-detection.
add_compiler_defaults = True
LOG.debug('parse_compile_commands_json: ' + str(add_compiler_defaults))

if output_path is not None:
remove_file_if_exists(os.path.join(output_path,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it always applicable for incremental analysis to remove these files? What if analysis configuration changes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a problem. If the analysis configuration changes the compile database still remains the same. Compiler includes and targets do not depend on analysis configuration.

@@ -38,7 +38,7 @@ def setup_class(cls):
cls.src_file_name = "main.cpp"
cls.src_file_path = os.path.join(cls.tmp_dir,
cls.src_file_name)
cls.compiler = "g++"
cls.compiler = "clang++"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this change introduced?

Copy link
Contributor Author

@martong martong Oct 26, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a bug which is present since a while. cls.compiler is called with --target and gcc7 exits with an error (return value not equal with 0), however older gcc like gcc 4.8 just gives a warning and returns with 0.


# Create a compilation database.
build_log = [{"directory": self.test_workspace,
"command": "gcc -c " + source_file,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to gcc not existing on macOS systems, this way of creating a build log on the fly is prone to break macOS tests. See #824.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought gcc is a symbolic link to clang on macOS. https://stackoverflow.com/questions/19535422/os-x-10-9-gcc-links-to-clang
Has this changed in systems newer than El Capitan?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no macOS machine, so I'm not sure. There was definitely no such thing as gcc and g++ on the Travis macOS instances a few months ago.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this is really a problem since there are several other uses like this in other test cases:

tests/functional/analyze/test_analyze.py|102 col 35| "command": "gcc -c " + source_file,
tests/functional/analyze/test_analyze.py|172 col 35| "command": "gcc -c " + source_file,
tests/functional/analyze/test_analyze.py|205 col 35| "command": "gcc -c " + source_file,
tests/functional/analyze/test_analyze.py|240 col 35| "gcc -c " + source_file)    
tests/functional/analyze/test_analyze.py|303 col 35| "command": "gcc -c " + source_file,
tests/functional/ctu/test_files/buildlog.json|4 col 17| "command": "gcc -c lib.c -o lib.o",  
tests/functional/ctu/test_files/buildlog.json|9 col 17| "command": "gcc -c main.c -o main.o",

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in this case compilation.json is not created on the fly, but wired in into the test case. So it will not cause problem on Mac.

@martong martong force-pushed the master branch 3 times, most recently from 5134a67 to 6bb7c51 Compare November 6, 2017 10:10
if os.path.exists(filename):
with open(filename, 'r') as f:
all_data = json.load(f)
all_data.update(data)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

be careful, this will not add a new member in the hash, but update an existing one. Thus you will always have one element in the dict such as {'target': 'arm', 'compiler': 'gcc-arm'}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in a new squashed commit

Copy link
Member

@dkrupp dkrupp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

On the long term however we may want to perform the compiler detection as a part of log and not analyze. The advantage would be that one would not need the presence of the compilers in the analysis phase (maybe the compilers exist only temporarily in the env).

@martong
Copy link
Contributor Author

martong commented Nov 6, 2017

We could not squash the merge commit 3df5ecd , so for simplicity we keep the 4 commit.
Next time I will rebase and will not create a separate merge commit.

@martong martong merged commit cb144db into Ericsson:master Nov 6, 2017
@gyorb gyorb added this to the release 6.2 milestone Nov 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer 📈 Related to the analyze commands (analysis driver)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants