Skip to content

Commit

Permalink
Tidy hash generation bugfixes
Browse files Browse the repository at this point in the history
On server side the linecache Python module cached the files from which
it returned a given line. If the file changed and the file was queried
from the cache then the given line returned from the old file version.

In case of ClangTidy the bug hash is generated by CodeChecker. Because
of the previous bug a false bug hash was generated if the line number of
the bug event changed. So now the bug hash is computed on client side
and is written to the .plist file. Server will use this hash instead of
generating it again.

When a bug path changed because it is shifted a few lines downer then
the corresponding line number was only updated in BagPathEvent and
BugReportPoint tables, but not in Report table. This caused a GUI
glitch, i.e. it didn't jump to the correct position when a report was
opened.
  • Loading branch information
bruntib committed Nov 13, 2017
1 parent f66e5e5 commit 89b547b
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 7 deletions.
8 changes: 8 additions & 0 deletions libcodechecker/analyze/store_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,15 +359,23 @@ def addReport(storage_session,
report.detection_status == 'unresolved' or \
report.detection_status == 'reopened':
new_status = 'unresolved'

report.file_id = file_id
report.line = line_num
report.column = column

change_path_and_events(session,
report.id,
bugpath,
events)
elif report.detection_status == 'resolved':
new_status = 'reopened'

report.file_id = file_id
report.line = line_num
report.column = column
report.fixed_at = None

change_path_and_events(session,
report.id,
bugpath,
Expand Down
16 changes: 11 additions & 5 deletions libcodechecker/analyze/tidy_output_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
"""

import copy
import hashlib
import json
import os
import plistlib
import re

from libcodechecker.logger import LoggerFactory
from libcodechecker.report import generate_report_hash
from libcodechecker.util import get_line

LOG = LoggerFactory.get_new_logger('TIDY OUTPUT CONVERTER')

Expand Down Expand Up @@ -252,13 +255,14 @@ def _add_files_from_messages(self, messages):

return fmap

def _add_diagnostics(self, messages, fmap):
def _add_diagnostics(self, messages, files):
"""
Adds the messages to the plist as diagnostics.
"""

fmap = self._add_files_from_messages(messages)
for message in messages:
diag = PListConverter._create_diag(message, fmap)
diag = PListConverter._create_diag(message, fmap, files)
self.plist['diagnostics'].append(diag)

@staticmethod
Expand All @@ -275,7 +279,7 @@ def _get_checker_category(checker):
return parts[0]

@staticmethod
def _create_diag(message, fmap):
def _create_diag(message, fmap, files):
"""
Creates a new plist diagnostic from a single clang-tidy message.
"""
Expand All @@ -298,6 +302,9 @@ def _create_diag(message, fmap):
diag['path'].append(PListConverter._create_event_from_note(message,
fmap))

diag['issue_hash_content_of_line_in_context'] \
= generate_report_hash(diag['path'], files, message.checker)

return diag

@staticmethod
Expand Down Expand Up @@ -366,8 +373,7 @@ def add_messages(self, messages):
Adds the given clang-tidy messages to the plist.
"""

fmap = self._add_files_from_messages(messages)
self._add_diagnostics(messages, fmap)
self._add_diagnostics(messages, self.plist['files'])

def write_to_file(self, path):
"""
Expand Down
4 changes: 2 additions & 2 deletions libcodechecker/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
"""
import hashlib
import json
import linecache
import os

from libcodechecker.logger import LoggerFactory
from libcodechecker.util import get_line

LOG = LoggerFactory.get_new_logger('REPORT')

Expand Down Expand Up @@ -84,7 +84,7 @@ def compare_ctrl_sections(curr, prev):
from_col = m_loc.get('col')
until_col = m_loc.get('col')

line_content = linecache.getline(source_file, source_line)
line_content = get_line(source_file, source_line)

if line_content == '' and not os.path.isfile(source_file):
LOG.debug("Failed to generate report hash.")
Expand Down
17 changes: 17 additions & 0 deletions libcodechecker/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,3 +320,20 @@ def escape_like(string, escape_char='*'):
return string.replace(escape_char, escape_char * 2) \
.replace('%', escape_char + '%') \
.replace('_', escape_char + '_')


def get_line(file_name, line_no):
"""
Return the given line from the file. If line_no is larger than the number
of lines in the file then empty string returns.
If the file can't be opened for read, the function also returns empty
string.
"""
try:
with open(file_name) as f:
for line in f:
line_no -= 1
if line_no == 0:
return line
finally:
return ''
4 changes: 4 additions & 0 deletions tests/unit/tidy_output_test_files/tidy1.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string>clang-analyzer-core.DivideZero</string>
<key>description</key>
<string>Division by zero</string>
<key>issue_hash_content_of_line_in_context</key>
<string>b650887dabcbf08d794479d8d9c652b1</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down Expand Up @@ -67,6 +69,8 @@
<string>clang-diagnostic-division-by-zero</string>
<key>description</key>
<string>remainder by zero is undefined</string>
<key>issue_hash_content_of_line_in_context</key>
<string>bca09efe4267ef0163e1f394a5a75bd8</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/tidy_output_test_files/tidy2.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string>clang-diagnostic-unused-variable</string>
<key>description</key>
<string>unused variable 'y'</string>
<key>issue_hash_content_of_line_in_context</key>
<string>4c083baab17b40be6d5a17559a3ea201</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down Expand Up @@ -50,6 +52,8 @@
<string>clang-analyzer-core.DivideZero</string>
<key>description</key>
<string>Division by zero</string>
<key>issue_hash_content_of_line_in_context</key>
<string>2ab193b22a3265993117b7de7df4a355</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down Expand Up @@ -227,6 +231,8 @@
<string>clang-diagnostic-division-by-zero</string>
<key>description</key>
<string>remainder by zero is undefined</string>
<key>issue_hash_content_of_line_in_context</key>
<string>c39585dc3ea7901a0c03a7dd037ce466</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down
4 changes: 4 additions & 0 deletions tests/unit/tidy_output_test_files/tidy3.plist
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<string>modernize-use-nullptr</string>
<key>description</key>
<string>use nullptr</string>
<key>issue_hash_content_of_line_in_context</key>
<string>e976c8a460a61557de3fffd60210a142</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down Expand Up @@ -67,6 +69,8 @@
<string>clang-analyzer-core.NullDereference</string>
<key>description</key>
<string>Dereference of null pointer (loaded from variable 'x')</string>
<key>issue_hash_content_of_line_in_context</key>
<string>79e3b2487b87569cbf062ad7ff3ce321</string>
<key>location</key>
<dict>
<key>col</key>
Expand Down

0 comments on commit 89b547b

Please sign in to comment.