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

[report-converter] LeakSanitizer Parser #3368

Merged
merged 3 commits into from
Jul 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/supported_code_analyzers.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ CodeChecker result directory which can be stored to a CodeChecker server.
| [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html) ||
| [UndefinedBehaviorSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) ||
| [DataFlowSanitizer](https://clang.llvm.org/docs/DataFlowSanitizer.html) ||
| [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html) | |
| [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html) | |

We support to convert multiple sanitizer output to a CodeChecker report
directory which can be stored to a CodeChecker server by using our
Expand Down
21 changes: 18 additions & 3 deletions docs/tools/report-converter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ a CodeChecker server.
* [Address Sanitizer](#address-sanitizer)
* [Memory Sanitizer](#memory-sanitizer)
* [Thread Sanitizer](#thread-sanitizer)
* [Leak Sanitizer](#leak-sanitizer)
jay24rajput marked this conversation as resolved.
Show resolved Hide resolved
* [Cppcheck](#cppcheck)
* [Spotbugs](#spotbugs)
* [Facebook Infer](#facebook-infer)
Expand Down Expand Up @@ -62,9 +63,9 @@ optional arguments:
-t TYPE, --type TYPE Specify the format of the code analyzer output.
Currently supported output types are: asan, clang-
tidy, coccinelle, cppcheck, cpplint, eslint,
fbinfer, golint, kernel-doc, mdl, msan, pyflakes,
pylint, smatch, sparse, sphinx, spotbugs, tsan,
tslint, ubsan.
fbinfer, golint, kernel-doc, lsan, mdl, msan,
pyflakes, pylint, smatch, sparse, sphinx, spotbugs,
tsan, tslint, ubsan.
--meta [META [META ...]]
Metadata information which will be stored alongside
the run when the created report directory will be
Expand Down Expand Up @@ -97,6 +98,7 @@ Supported analyzers:
fbinfer - Facebook Infer, https://fbinfer.com
golint - Golint, https://github.com/golang/lint
kernel-doc - Kernel-Doc, https://github.com/torvalds/linux/blob/master/scripts/kernel-doc
lsan - LeakSanitizer, https://clang.llvm.org/docs/LeakSanitizer.html
mdl - Markdownlint, https://github.com/markdownlint/markdownlint
msan - MemorySanitizer, https://clang.llvm.org/docs/MemorySanitizer.html
pyflakes - Pyflakes, https://github.com/PyCQA/pyflakes
Expand Down Expand Up @@ -186,6 +188,19 @@ clang++ -fsanitize=thread -g tsan.cpp
report-converter -t tsan -o ./tsan_results tsan.output
```

### [Leak Sanitizer](https://clang.llvm.org/docs/LeakSanitizer.html)
- Compile with `-g` and `-fsanitize=address` to get proper debug information in your binary.
```sh
# Compile your program.
clang -fsanitize=address -g lsan.c

# Run your program and redirect the output to a file.
ASAN_OPTIONS=detect_leaks=1 ./a.out > lsan.output 2>&1

# Generate plist files from the output.
report-converter -t lsan ./lsan_results lsan.output

Choose a reason for hiding this comment

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

lost a "-o" option before "./lsan_results"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops! Let me fix that in a pull request!

Thanks for pointing it out 😄

Choose a reason for hiding this comment

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

You are welcome, and in addition , could you please help me to check issue #3373 if you have extra time,
I compiled the newest code this morning ,but I can not convert lsan report, even use the official leak sanitizer output, I am really confused now , I don't know which of my steps is wrong or maybe I lost something😥.

```

## [Cppcheck](http://cppcheck.sourceforge.net/)
[Cppcheck](http://cppcheck.sourceforge.net/) is a static analysis tool for
`C/C++` code.
Expand Down
3 changes: 3 additions & 0 deletions tools/report-converter/codechecker_report_converter/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
SparseAnalyzerResult # noqa
from codechecker_report_converter.cpplint.analyzer_result import \
CpplintAnalyzerResult # noqa
from codechecker_report_converter.sanitizers.leak.analyzer_result import \
LSANAnalyzerResult # noqa


LOG = logging.getLogger('ReportConverter')
Expand Down Expand Up @@ -105,6 +107,7 @@ class RawDescriptionDefaultHelpFormatter(
SphinxAnalyzerResult.TOOL_NAME: SphinxAnalyzerResult,
SparseAnalyzerResult.TOOL_NAME: SparseAnalyzerResult,
CpplintAnalyzerResult.TOOL_NAME: CpplintAnalyzerResult,
LSANAnalyzerResult.TOOL_NAME: LSANAnalyzerResult
}

supported_metadata_keys = ["analyzer_command", "analyzer_version"]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------


from codechecker_report_converter.analyzer_result import AnalyzerResult
from codechecker_report_converter.plist_converter import PlistConverter

from .output_parser import LSANParser


class LSANAnalyzerResult(AnalyzerResult):
""" Transform analyzer result of Clang LeakSanitizer. """

TOOL_NAME = 'lsan'
NAME = 'LeakSanitizer'
URL = 'https://clang.llvm.org/docs/LeakSanitizer.html'

def parse(self, analyzer_result):
""" Creates plist files from the given analyzer result to the given
output directory.
"""
parser = LSANParser()

content = self._get_analyzer_result_file_content(analyzer_result)
if not content:
return

messages = parser.parse_messages(content)

plist_converter = PlistConverter(self.TOOL_NAME)
plist_converter.add_messages(messages)
return plist_converter.get_plist_results()
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# -------------------------------------------------------------------------
#
# Part of the CodeChecker project, under the Apache License v2.0 with
# LLVM Exceptions. See LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# -------------------------------------------------------------------------


import logging
import re

from ...output_parser import get_next, Message, Event
from ..output_parser import SANParser

LOG = logging.getLogger('ReportConverter')


class LSANParser(SANParser):
""" Parser for Clang LeakSanitizer console outputs. """

def __init__(self):
super(LSANParser, self).__init__()

# Regex for parsing MemorySanitizer output message.
self.leak_line_re = re.compile(
# Error code
r'==(?P<code>\d+)==(ERROR|WARNING): LeakSanitizer: '
# Checker message.
r'(?P<message>[\S \t]+)')

def parse_sanitizer_message(self, it, line):
""" Parses LeakSanitizer output message.

The first event will be the main location of the bug.
"""
match = self.leak_line_re.match(line)
if not match:
return None, line

line = get_next(it)
stack_traces, events, line = self.parse_stack_trace(it, line)

if not events:
return None, line

main_event = events[-1]

notes = [Event(main_event.path, main_event.line, main_event.column,
''.join(stack_traces))]

return Message(main_event.path, main_event.line, main_event.column,
match.group('message').strip(),
"LeakSanitizer",
events, notes), line
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <stdlib.h>
void *p;
int main()
{
p = malloc(7);
p = 0; // The memory is leaked here.
return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
==23646==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x4af01b in __interceptor_malloc /projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3
#1 0x4da26a in main files/lsan.c:4:7
#2 0x7f076fd9cec4 in __libc_start_main libc-start.c:287
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s)
111 changes: 111 additions & 0 deletions tools/report-converter/tests/unit/lsan_output_test_files/lsan.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>diagnostics</key>
<array>
<dict>
<key>category</key>
<string>unknown</string>
<key>check_name</key>
<string>LeakSanitizer</string>
<key>description</key>
<string>detected memory leaks</string>
<key>issue_hash_content_of_line_in_context</key>
<string>37e6fc6c7fb792d5e91ac6c3dbbe46b0</string>
<key>location</key>
<dict>
<key>col</key>
<integer>7</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>4</integer>
</dict>
<key>notes</key>
<array>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>note</string>
<key>location</key>
<dict>
<key>col</key>
<integer>7</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>4</integer>
</dict>
<key>message</key>
<string>Direct leak of 7 byte(s) in 1 object(s) allocated from:
#0 0x4af01b in __interceptor_malloc /projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3
#1 0x4da26a in main files/lsan.c:4:7
#2 0x7f076fd9cec4 in __libc_start_main libc-start.c:287
SUMMARY: AddressSanitizer: 7 byte(s) leaked in 1 allocation(s)
</string>
</dict>
</array>
<key>path</key>
<array>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>event</string>
<key>location</key>
<dict>
<key>col</key>
<integer>7</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>4</integer>
</dict>
<key>message</key>
<string> #1 0x4da26a in main files/lsan.c:4:7</string>
</dict>
<dict>
<key>depth</key>
<integer>0</integer>
<key>kind</key>
<string>event</string>
<key>location</key>
<dict>
<key>col</key>
<integer>7</integer>
<key>file</key>
<integer>0</integer>
<key>line</key>
<integer>4</integer>
</dict>
<key>message</key>
<string>detected memory leaks</string>
</dict>
</array>
<key>type</key>
<string>lsan</string>
</dict>
</array>
<key>files</key>
<array>
<string>files/lsan.c</string>
</array>
<key>metadata</key>
<dict>
<key>analyzer</key>
<dict>
<key>name</key>
<string>lsan</string>
</dict>
<key>generated_by</key>
<dict>
<key>name</key>
<string>report-converter</string>
<key>version</key>
<string>x.y.z</string>
</dict>
</dict>
</dict>
</plist>
Loading