2.3. Exclude, Suppress and Justify Analysis Results¶
2.3.1. Exclude files from the Analysis¶
If you want to restrict some analysis to certain parts of the code, you can choose among different options:
When using
axivion_cioraxivion_analysis, you can configure the optionglobal_excludeson theAnalysisroot node. This will suppress all violations where the filename matches one of the configured glob patterns. This can be used, for example, to suppress all messages in 3rd-party code. System headers are excluded by default.You can use each rule’s option
excludesto define such exclusions for selected rules only. There is also the optionincludesto limit rules to a provided whitelist of directories. This can be used, for example, to apply different rules to different parts of the code, e.g. if you want to run only a subset of MISRA® checks on generated code.If you want to run some rule with different settings for different parts of the code, you can create copies of the rule and configure them independently; also use the above-mentioned options
includes/excludesto limit these copies to different code parts. This can be used, for example, to apply a rule to both generated and hand-written code, but with different (maybe relaxed) settings on the generated code.Several rules report different kinds of messages. If you want to suppress a specific kind of message (but continue to see all others), you can disable the message in the graphical configuration interface under the option
msgof the rule. You will see the messages generated by the rule there, and for each such message you will find the nested optiondisabledthat you can set to True in order to suppress this specific kind of message. If you only want to change the wording of the message, you can do so here as well by setting the optiontextof the message to the desired text.To disable individual issues, you can place special code annotations (markup comments) in the code. Some code annotations can also be specified in configuration files if you want to avoid modifying the code. Code annotations are described in Justifications and Suppressions with Code Annotations. You can also use this feature to only mark affected issues as suppressed, but still import them into the database, so you can inspect them in the dashboard or include them in reports.
2.3.2. Justifications and Suppressions with Code Annotations¶
You can place special comments and pragmas in the source code in order to suppress the reporting of specific issues in the dashboard, or to attach some justification (permit, annotation) to reported issues. These special comments are called control comments or commentary activators. The following features are supported:
Suppressing issues (both with in-code annotations and from configuration)
Adding justifications to issues (both with in-code annotations and from configuration)
Checking for presence of a justification
Checking the contents of a justification
Showing suppressed issues in the dashboard
Respecting code annotations created for other tools
Using your own syntax for the code annotations
Affecting different code portions with different code annotations
Selecting affected issues based on different issue properties
Reporting stale (unused) code annotations
This chapter helps you to get started with the code annotation feature. It shows you how to use the default suppressions and justifications at:
As well as how to:
And some example uses.
2.3.2.1. Suppressions and Justifications at Line level¶
To suppress and justify issues in specific lines in the source code, proceed as follows:
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/LineBasedSuppressions/NextLineand activate that rule.In your source code, in the line immediately preceding the line in which you want to suppress an issue, write a corresponding comment, for example:
// AXIVION Next Line MisraC2012-20.5: AUTOSAR permittedThis comment would suppress issues from rule MisraC2012-20.5 in the next line. Additionally, this comment provides a justification for the suppression, namely the text behind the colon.
If you instead prefer to write the comment in the same line in which the issue
is reported or in the next one, then simply activate rule SameLine or
PreviousLine instead of NextLine.
Note
If you intend to use 2 NextLine suppressions in the following way:
// AXIVION Next Line MisraC2012-1.2: justification
// AXIVION Next Line MisraC2012-1.3: justification
<code here>
then you should instead use NextCodeLine
as the <code here> example above would only have MisraC2012-1.3 suppresssed.
2.3.2.2. Suppressions and Justifications at Region level¶
There are multiple ways to suppress sections of code. The pre-configured suppression formats that Axivion provides and which will be explained in this chapter are:
EnableDisable: Enable/disable issue reporting for code sections using start/end markers
ConstructBasedSuppressions: Suppress issues for specific code constructs
RoutineBasedSuppressions: Suppress issues for entire functions/methods
FileWide: Suppress issues for complete source files
Each of these formats serves different needs and provides flexibility in how you manage suppressions across multiple lines of code. Let us look at how to configure and use each of these formats.
Enable/Disable Suppressions¶
To suppress and justify issues in sections of the source code with EnableDisable, proceed
as follows:
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/EnableDisableand activate that rule.In your source code, write a comment that disables the reporting of issues in the following lines, for example:
// AXIVION DISABLE Style MisraC2012-20.5: AUTOSAR permittedThis comment would suppress issues of kind
Stylechecksfrom ruleMisraC2012-20.5in the following lines. Additionally, this comment provides a justification for the suppression, namely the text after the colon.To re-enable issue reporting, write a comment that enables the reporting of issues in the following lines, for example:
// AXIVION ENABLE Style MisraC2012-20.5This comment would re-enable issues from rule MisraC2012-20.5 in the following lines.
Note
The enable comment can also be used to re-enable all issues that were disabled by a previous disable comment, by not specifying a rule name.
If you wish to to have some files with a rule suppressed by default, but that can still be enabled in the file itself, you can additionally follow the steps below:
In the graphical configuration interface, navigate to
AnalysisControl/CodeAnnotations/ExternalCodeAnnotations/InitialExternalAnnotationsand activate that rule.That rule on the right-hand side of the GUI has an option
initial_commentsin which you can write the code annotations that should apply to issues in selected files. Double-click on that option to change its value and create new entries, for example:Filename pattern *.inc and value AXIVION DISABLE
Filename pattern *MemMap*.h and values
AXIVION DISABLE Style MisraC2012-20.5: AUTOSAR permitted AXIVION DISABLE STYLE MisraC-1.1 : nesting level of #if is not in scope of memmap (AUTOSAR)
These comments would suppress the rules mentioned in the comment (MisraC2012-20.5 resp. MisraC-1.1) in all files matching the given globbing patterns (extension
.incfor the first case and header filenames containing the substringMemMapfor the second). Additionally, these comments provide a justification for the suppressions, namely the text after the colon.Note
These examples used the keyword Style to restrict the comment to stylecheck issues. In general, when a format allows the selection of issue kind like this, you can use the following keywords:
Style or Stylecheck for stylecheck issues
Metric or Metrics for metric issues
Architecture for architecture issues
Clone or Clones for clone issues
Cycle or Cycles for cycle issues
Dead or DeadCode for dead code issues
All for all issue kinds
Construct-Based Suppressions¶
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/ConstructBasedSuppressionsand activate one of the rules bellow.The construct-based suppressions allow you to suppress issues in specific code constructs (statements/declarations). The following types are available:
NextCodeline: Suppresses issues in the first line of the next statement, declaration, #line or #pragma
NextConstruct: Suppresses issues in the next construct (statement/declaration)
PreviousConstruct: Suppresses issues in the previous construct
SameConstruct: Suppresses issues in the same construct
For example, using
Next Construct:/* AXIVION Next Construct MisraC2012-15.4: Suppresses the entire if statement */ if (condition) { // This line is suppressed doSomething(); // This line is suppressed too }
The format is similar for all types, just replace
Next Constructwith the appropriate type.
Routine-Based Suppressions¶
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/RoutineBasedSuppressionsand activate one of the rules bellow.Routine-based suppressions allow you to suppress issues in entire functions. The following types are available:
NextRoutine: Suppresses issues in the next routine
PreviousRoutine: Suppresses issues in the previous routine
SameRoutine: Suppresses issues in the current routine
SelectedRoutine: Suppresses issues in a specifically named routine
For example, using Selected Routine:
/* AXIVION Selected Routine MyFunction MisraC2012-15.4: Suppresses the entire routine */ void MyFunction(void) { // This line is suppressed doSomething(); // This line is suppressed too doSomethingElse(); }
The format is similar for all types (except Selected Routine which requires the routine name), just replace
Selected Routine MyFunctionwith the appropriate type.
File-Wide Suppressions¶
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/FileWideand activate that rule.FileWide suppressions allow you to suppress issues in an entire source file by placing a single comment anywhere in the file. For example:
/* AXIVION FILE Style MisraC2012-20.1: my justification */This comment would suppress all issues from rule MisraC2012-20.1 in the entire file. Additionally, this comment provides a justification for the suppression, namely the text after the colon.
2.3.2.3. Suppressions and Justifications at Project level¶
To suppress and justify issues in the complete project, proceed as follows:
In the graphical configuration interface, navigate to
Analysis/AnalysisControl/CodeAnnotations/Suppressions/ProjectWideand activate that rule.ProjectWide suppressions allow you to suppress issues in the entire project by placing a single comment anywhere in the analyzed code. For example:
/* AXIVION EXCEPTION Style MisraC2012-20.1 *MemMap*.h: my justification */This comment would suppress all issues from rule MisraC2012-20.1 in the entire project, where the file name matches the pattern
*MemMap*.h. Additionally, this comment provides a justification for the suppression, namely the text after the colon.If you do not want to place the comment randomly in the code, you can also use an additional rule that allows Axivion Suite to internally add the comment to the project. In the graphical configuration interface, navigate to
AnalysisControl/CodeAnnotations/ExternalCodeAnnotations/ProjectWideExternalAnnotationsand activate that rule.That rule on the right-hand side of the GUI has an option
project_commentsin which you can write the code annotations that should apply to all of the analyzed code. Double-click on that option to change its value and create new entries, for example:AXIVION EXCEPTION STYLE MisraC2012-20.1 \*MemMap\*.h : AUTOSAR permitted AXIVION EXCEPTION STYLE MisraC-19.6 \*START_SEC\* : THIS IS PERMITTED for Memmap defines
These comments would suppress the rules mentioned in the comment (MisraC2012-20.1 resp. MisraC-19.6), but only those cases where the reported entity matches the given name pattern (
\*MemMap\*.hresp.\*START_SEC\*). Additionally, these comments provide a justification for the suppressions, namely the text behind the colon.
2.3.2.4. Suppressed Issues in Reports and in the Dashboard¶
By default, issues suppressed by such code annotation comments will not be reported.
In case you need to know about these suppressed issues (e.g., for
a complete MISRA® audit report), you can import them into the database.
This can be done by setting option /Results/Database/import_suppressed_issues
to True in the graphical configuration interface. With this option, suppressed issues
are
imported into the database,
shown in the dashboard,
and available for reports.
Alternatively, you can also select
comment formats which just add justifications to issues, without suppressing them.
You will find them in the graphical configuration interface inside the rule group
AnalysisControl/CodeAnnotations/NonSuppressingIssueComments.
Therefore you can distinguish these scenarios:
Issue is not suppressed and has no justification (e.g. an issue in your code that still needs inspection)
Issue is not suppressed but has a justification (e.g. an issue in your code that was already inspected and dealt with in form of a deviation)
Issue is suppressed and has no justification (e.g. an issue in third-party code which was not inspected)
Issue is suppressed but has a justification (e.g. an issue in third-party code which was inspected)
The last two cases are only shown when the above-mentioned flag is set, so you can choose whether you want to see issues in third-party code or not.
2.3.2.5. Defining a code annotation format¶
The above examples show simple uses of the code annotation feature. You can start with them to get familiar with the topic. In every case you have to select the comment format(s) that you want to support in your code annotation comments. Several such formats are already included in the standard installation so that it is sufficient to just activate them as needed. They differ, for example, in the comment syntax or the code region being affected.
But if you want to enable more advanced use-cases, you need to tell the Axivion Suite
the format of the comments that should be recognized as special code annotations.
The available comment formats can be selected in the graphical configuration interface under
AnalysisControl/CodeAnnotations. There, subcategory
Suppressions provides predefined formats for comments that should
suppress issues (and optionally do more, like adding a suppression), while subcategory
NonSuppressingIssueComments provides predefined formats that only add
justifications without suppressing.
Choose the format(s) that match your needs, and if necessary, adapt the options
to e.g. use your company’s name instead of Axivion in the comments.
As with other configuration items, you can copy and rename such formats to create
independent copies that have independent configurations. This can be used to
design your own comment formats instead of changing one of the predefined formats.
A Code Annotation’s format field expects a regular expression (regex) pattern
that can contain capture groups. A capture group is created by enclosing a part of the
pattern in parentheses ().
Example using default settings of Selected Routine regex with 3 groups:
\s*AXIVION\s+Selected\s+Routine\s+(\S*)\s+([^:]*)(:.*)?
Group 0 - The full matched string
Group 1 - (\S*)
Group 2 - ([^:]*)
Group 3 - (:.*)?
Then, for each option of the suppression’s rule, such as entity, kind,
justification, rule etc etc, you can select it to either:
Not apply to this suppression, by setting the
valuetoNoneTo apply with a static value, which is selected in
axivion_config, by setting thevalueto the desired constTo apply and have a dynamic value that will depend on the
valueset, and on one of the regex groups of the suppression comment.
As an example, for the default values that are set on the Selected Routine
example from above, we have the following options configured:
Action- Statically set toSUPPRESSEntity- does not applyJustification- Due tovaluebeing set toAFTER_COLONit will dynamically catch whatever comes in the3rd groupof the regex -(:.*)?Kind- Statically set toSTYLEMacro- does not applyMessage- does not applyMessage_key- does not applyRule- Due tovaluebeing set toAXIVION_NAMESit will dynamically catch whatever rule comes in the2nd groupof the regex -([^:]*)Scope- Due tovaluebeing set toROUTINE_BY_NAMEit will dynamically catch whatever routine comes in the1st groupof the regex -(S*)
To understand what each value expects, please read the descriptiom of it in the
UI of axivion_config.
To suppress architecture violations, you can access the rule name of an issue as for style check issues. Additionally, the message_key of the comment can be used to limit affected architecture violations by the type of the reflexion edge (e.g., Divergence), and the message can be used to limit by the type of the causing edge (e.g., Static_Call).
Python configuration and custom parser¶
Some options may not (yet) be supported in the graphical configuration interface; in that case, add a Python layer to your configuration and in that file set the remaining properties (see configuration system).
This is especially the case if for some option you need a different approach
for parsing the required field information from a comment than those being
available for selection. In such a case, select the option CUSTOM_PARSER
as the option’s value and on the Python side set the attribute custom_parser
to your Python function.
The signature of such a custom parser should be
def my_parser(comment, text) or def my_parser(comment, text, issue)
where the first two parameters denote a representation of the full comment
and the string that matched the specified group in the format’s regular expression.
The optional third parameter provides details on the issue for which the
comment is checked (i.e., issue kind and rule name).
Note: Because the Axivion Suite analysis is distributed over multiple processes,
a custom parser using the three-parameter form might be serialized (using Python
pickle) and deserialized in another process. Effectively, this means you can
only use top-level Python functions, not lambdas.
2.3.2.6. Code annotations outside source files¶
Besides special comments in the code, the Axivion Suite also supports code annotations from within the configuration. This can be useful if
you do not want to touch the source files,
if the files are generated and thus changes would be lost,
if you want to affect issues in line 1 of a file,
or if you want to suppress certain issues project-wide.
For project-wide code annotations, use the graphical configuration interface and select
the format AnalysisControl/CodeAnnotations/Suppressions/ProjectWide as well as
AnalysisControl/CodeAnnotations/ExternalCodeAnnotations/ProjectWideExternalAnnotations.
This rule has an option project_comments in which you can write the code
annotations that should apply to all of the analyzed code. The annotations here
have to match the format
AnalysisControl/CodeAnnotations/Suppressions/ProjectWide or any other selected
format with the scope Project. Again, adapt the syntax of the project-wide comment
format to your needs or create copies of the format as necessary.
To add other code annotations from within the configuration, select
AnalysisControl/CodeAnnotations/ExternalCodeAnnotations/InitialExternalAnnotations.
The code annotations configured here in option initial_comments are considered like
comments at the very beginning of each affected file and should match one of your
selected comment formats.
2.3.2.7. Checking justifications¶
The justifications which can be attached to issues by code annotations are free-form
text. However, you may want to impose certain rules for these strings, e.g. that they
have to refer to a Misra permit. This can be done by setting a custom
Python function as value of the option justification_checker which is present
at all rules generating issues (each such rule can have a different callback).
As this must be a Python function, it can only be configured in a Python configuration
layer. This callback function can update the issue, for example to remove the
disabled-Flag when the justification does not match the required format.
An example using this feature (it forbids suppressing issues without
providing a justification):
def disallow_unjustified_deviations(issue):
# forbid suppressing without justification
if issue.disabled:
if not issue.justification:
issue.disabled = False
import axivion.config
analysis = axivion.config.get_analysis()
for rule_name in analysis.get_active_rules():
if hasattr(analysis[rule_name], 'justification_checker'):
analysis[rule_name].justification_checker = disallow_unjustified_deviations
2.3.2.8. Example Uses¶
Besides standard issue suppressing and justification, the flexibility of scriptable code annotation formats also allows more sophisticated uses. The examples provided here leverage the ability to map the rule identification as written in the comment to something else.
2.3.2.9. Migrating from one coding standard to another¶
When your organization switches from an older standard to a newer one, rule names may have changed in those standards although the rules still cover similar or identical aspects. This means you have to update all code annotations to replace the old name with the new one. For example, when migrating from Misra-C:2004 to Misra-C:2012, an annotation suppressing MisraC-2.1 has to be changed to mention MisraC2012Directive-4.3 instead.
To simplify this migration, a comment format can be used that accepts the old (Misra-C:2004) rule names, but returns corresponding new (Misra-C:2012) rule names as rule selection. This would allow to use the old code annotations for cases where the new standard has a counterpart. To define a suitable comment format, set its rule value to CUSTOM_PARSER and, in a Python configuration file, set the rule custom parser field to a Python function that returns the desired list of Axivion rule names:
def rule_parser_for_migration(comment, text):
# text is the part of the comment denoting the rule (as written in the comment)
# now map those names to the desired new rule names
updated_rules = [...]
return updated_rules
import axivion.config
from axivion.config import code_annotations
analysis = axivion.config.get_analysis()
analysis['YourCommentFormat'].rule.value = code_annotations.Rule.CUSTOM_PARSER
analysis['YourCommentFormat'].rule.custom_parser = rule_parser_for_migration
You can also use standard-independent, generic rule names and map those to actual rule names from either or both standards.
2.3.2.10. Migrating from lint and other tools¶
If you previously used other static code analysis tools (like lint), you may already have code annotations for these tools. Instead of rewriting them you can also define a comment format that syntactically accepts the format of the other tool, but returns Axivion rule names instead. Such a mapping between rule names can be done with CSV files, for example, that are read in the Python function listed as rule-selection parser.
2.3.2.11. Using multiple analysis tools¶
If you use multiple analysis tools (for example, Axivion, lint, and self-made checkers),
you can import the results of the other tools into the Axivion database using
the analysis rules ImportExternalAnalysisOutput or :code`Generic-ImportCSV`.
They will be imported like style violations using as rule name what the CSV file
provides in column errno.
To avoid having to write multiple code annotations - one per tool - for the same issue, you can also come up with your own general rule names and map those in the rule-selection parser to actual rule names for the different tools (the mapping can return a list of rules for a single code annotation). For example, your general rule name could be mapped to
['MisraC-2.1', 'lint-123', 'MyCompany-ABC']
As the code annotations are also used for imported style violations, you can in this way suppress or justify third-party messages. Just ensure the rule names returned by your rule-selection parser match the errno field from the CSV file. Then you have a setup where all tools can be executed with the combined set of messages being displayed in a single dashboard, and being suppressed and justified in a common way without duplicating code annotations.
Referring to Permits¶
In safety-critical projects a suppression for an issue usually requires some kind
of permit to do so. This reference to a permit can be put into the justification
of a code annotation, and the justification_checker feature can be used
to ensure that all suppressions refer to an appropriate permit
(see section Checking justifications).
This example creates a comment format that allows comments like this one:
Example code with comment referring to permits¶#define _MY_MACRO // Permit 21.1-DPS211 Permit 17.0.1-DPS1701
Here we assume that the piece of code is checked by both MisraC2012-21.1 and MisraC++-17.0.1 (e.g. a header in a mixed C/C++ project). Both these rules report a violation in the given line, and the comment should suppress those and refer to a different permit per rule.
For this comment format, we start by copying the existing format
SameLine and give the copy its own name, for example Misra Permits.
This new rule is then activated, and a few options of it must be changed.
That can be done in the graphical configuration interface, but we show it here
in Python, as the subsequent configuration parts require Python anyway:
Python configuration layer for Misra Permits comment format¶import re import axivion.config from axivion.config import code_annotations analysis = axivion.config.get_analysis() format_permits = analysis.copy('SameLine', 'Misra Permits') analysis.activate('Misra Permits') # .. utility functions described below, have to be inserted here .. format_permits.format = '(\s*Permit\s+(\d+\.\d+\.*\d*)-DPS(\d*))+' format_permits.rule.group = 0 format_permits.rule.value = code_annotations.Rule.CUSTOM_PARSER format_permits.rule.custom_parser = extract_rulename format_permits.justification.group = 0 format_permits.justification.value = code_annotations.Justification.CUSTOM_PARSER format_permits.justification.custom_parser = extract_permit
This example uses custom parser functions which can only be defined in Python. They are used here to extract the rule name from the comment, and to extract the appropriate permit. Let us first look at the utility function to extract the rule name:
Custom Python parser to extract the rulename from the comment¶def extract_rulename(comment, text): '''Returns the Axivion rule name(s) to disable based on the comment. The result can be a globbing pattern. The text argument in this case is the complete string as this is the only way to access all subgroups in all repetitions.''' pattern = r'\s*Permit\s+(\d+\.\d+\.*\d*)-DPS(\d*)\s*' rules = [] for match in re.findall(pattern, text): rulenumber = match[0] if rulenumber.count('.') == 2: rulename = 'MisraC++-%s' % rulenumber else: rulename = 'MisraC2012-%s' % rulenumber rules.append(rulename) return rules
This function is used to return the proper rule names to look for when checking
whether an issue is affected by the comment. In our example, the comment is
Permit 21.1-DPS211 Permit 17.0.1-DPS1701 and the function returns
the rule names ['MisraC++-17.0.1', 'MisraC2012-21.1'].
For the associated permit, we need another custom parser, and this function requires the issue details in order to match the issue with the appropriate part of the comment. The Python function looks like this:
Custom Python parser to extract the permit for an issue¶def extract_permit(comment, text, issue): '''Returns the justification to use for suppressing the message. The input text will be the complete string as this is the only way to access all subgroups in all repetitions.''' assert issue.kind == code_annotations.IssueKind.STYLE rule_name = issue.rule_name pattern = r'\s*Permit\s+(\d+\.\d+\.*\d*)-DPS(\d*)\s*' permits = [] for match in re.findall(pattern, text): rulenumber = match[0] if rulenumber.count('.') == 2: this_rulename = 'MisraC++-%s' % rulenumber else: this_rulename = 'MisraC2012-%s' % rulenumber if this_rulename == rule_name: permit = 'Permit %s-DPS%s' % (match[0], match[1]) permits.append(permit) result = '; '.join(permits) return result
This function returns the permit given in the comment for the rule name of the issue.
For example, for the MisraC2012-21.1 issue, it returns Permit 21.1-DPS211,
and that will be used as the justification of the suppressed issue.
The justification_checker feature can now be used
to ensure that all suppressions refer to an appropriate permit
(see section Checking justifications).