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

Rework system outputting warnings #201

Closed
Wherekonshade opened this issue Apr 22, 2021 · 8 comments · Fixed by #255
Closed

Rework system outputting warnings #201

Wherekonshade opened this issue Apr 22, 2021 · 8 comments · Fixed by #255
Assignees
Labels
cleanup Refactoring, clean-up feature practical-course Practical Course at TUM usability

Comments

@Wherekonshade
Copy link
Contributor

Categories should be introduced to create a better understanding of the warnings.

#198 #199 #200
@vandah
@EdinCitaku

@michael-schwarz michael-schwarz added cleanup Refactoring, clean-up feature practical-course Practical Course at TUM labels Apr 22, 2021
@michael-schwarz
Copy link
Member

For this you might want to also take a look at #55 that addresses the same issue

Goals:

  • usability: allow filtering
  • type-safety: avoid having different strings for the same thing
  • testing/traceability: e.g. change leads to less warnings for category x

Implementation:

  • list of tags? e.g. warn maybe [Undefined; Integer] "..."

open type for categories:

  • Behavior
  • Undefined
  • Implementation
  • Machine
  • Integer
  • Overflow
  • Div_by_zero
  • Cast
  • Type_mismatch (bug)
  • Race
  • Array
  • Out_of_bounds of int*int

@michael-schwarz
Copy link
Member

Also relevant #36

@Wherekonshade
Copy link
Contributor Author

Wherekonshade commented Jun 10, 2021

There are some things open to discussion for the implementation of this issue. If you have any thoughts on the following please let us know :)

  1. The categories will be based on the a fore mentioned list for a start:
  • Unknown
    
  • Behavior
    
  • Undefined
    
  • Implementation
    
  • Machine
    
  • Integer
    
  • Overflow
    
  • Div_by_zero
    
  • Cast
    
  • Type_mismatch (bug)
    
  • Race
    
  • Array
    
  • Out_of_bounds of int*int
    
  1. The user should be able to enable/disable each of these categories individually

  2. Reports and warnings should be merged with this new approach.

  3. The new warning will show the category and also a "must" or "may" tag, which will be "may" by default.

5. If possible the warning will be constructed completely at the place of origin

@vogler
Copy link
Collaborator

vogler commented Jun 11, 2021

Your formatting misses the structure from #55:

open type for categories:

  • Behavior

    • Undefined
    • Implementation
    • Machine
  • Integer

    • Overflow
    • Div_by_zero
  • Cast

    • Type_mismatch (bug)
  • Race

  • Array

    • Out_of_bounds of int*int

I assume we want to reflect the structure in the type (or some value) to be able to easily filter whole groups.
There are open questions:

  1. do we want it flat and unqualified with polymorphic variants or do we want normal variants which might not be as convenient to write but are possibly safer?
  2. do we want the type definition in one place or distributed with extensible variants (does not work with polymorphic variants)?

Untested and not all combinations, but should give some idea:


Extensible variants:
e.g. messages.ml:

type group = ..
let is_integer_error = function Integer _ -> true | _ -> false

e.g. intDomain.ml:

type integer_error = Overflow | Div_by_zero
type Messages.group += Integer of integer_error

e.g. base.ml:

open Messages
(* ... *)
warn `Must (Integer IntDomain.Div_by_zero) "..."

Normal variants all in one place:
e.g. messages.ml:

type integer_error = Overflow | Div_by_zero
type group = Integer of integer_error (* | ... *)
let is_integer_error = function Integer _ -> true | _ -> false

e.g. base.ml:

open Messages
(* ... *)
warn `Must (Integer Div_by_zero) "..."

Flat polymorphic variants:
e.g. messages.ml:

let is_integer_error = function `Overflow | `Div_by_zero -> true | _ -> false

e.g. base.ml:

(* ... *)
Messages.warn `Must `Div_by_zero "..."

@sim642
Copy link
Member

sim642 commented Jun 11, 2021

4. The new warning will show the category and also a "must" or "may" tag, which will be "may" by default.

As always, my worry with this is our fabulous PathSensitive2 functor. There has to be some kind of interaction between these must/may tags and multiple paths reaching the same location/node. For example, if a must warning is emitted while analyzing one path, but no warning is emitted while analyzing the other, then overall for that location/node it's actually a may warning. So the lack of a warning also matters for such aggregation. Or what is the intent on dealing with path-sensitivity?

Not sure if this is related to warnings or not, but our assertion result reporting has the same issue. Different results on different paths must meaningfully combine. For example, a must-success on one path and a must-failure on another path make up an unknown result.

5. If possible the warning will be constructed completely at the place of origin

What does this mean?

@michael-schwarz
Copy link
Member

As always, my worry with this is our fabulous PathSensitive2 functor. There has to be some kind of interaction between these must/may tags and multiple paths reaching the same location/node. For example, if a must warning is emitted while analyzing one path, but no warning is emitted while analyzing the other, then overall for that location/node it's actually a may warning. So the lack of a warning also matters for such aggregation. Or what is the intent on dealing with path-sensitivity?

This is then compounded by the issue of different contexts as well. One possible way to think about this would be: A warning is a must warning if there is a must warning for all paths in all contexts that are deemed reachable.

Even this however does still not correspond to something that must happen in the concrete: Even in a case without path splitting and only one context, the entire program point may only be reachable due to overapproximation.

However, as a first approach I would suggest the semantics of a must warning to be that there exists at least one path and context where the problem must happen when reaching the program point it in the corresponding context and with a value described by the predecessor.

@Wherekonshade
Copy link
Contributor Author

Wherekonshade commented Jun 11, 2021

5. If possible the warning will be constructed completely at the place of origin

What does this mean?

  1. was just supposed to mean, that we want to add the category and the must or may tag as well as additional info for the output to the user all at the place where the warning happens instead of doing it centrally in messages.ml for example. Sorry for the imprecise formulation.

@sim642
Copy link
Member

sim642 commented Jul 23, 2021

I was looking deeper into Messages now for #297 and realized something which is not really addressed by #255. Namely, there's this warnings table:

let warning_table : [`text of string * location | `group of string * ((string * location) list)] list ref = ref []

Warnings get added to this table for HTML and GobView output, in addition to being printed on the terminal:
let push_warning w =
if get_string "result" = "fast_xml" || get_bool "gobview" then
warning_table := w :: !warning_table

To my surprise, the warnings table has support for grouped warnings, which are used for data races:
let print_group group_name errors =
(* Add warnings to global warning list *)
push_warning (`group (group_name, errors));
let f (msg,loc): doc = Pretty.dprintf "%s (%s:%d)" msg loc.file loc.line in
if (get_bool "ana.osek.warnfiles") then begin
match (String.sub group_name 0 6) with
| "Safely" -> ignore (Pretty.fprintf !warn_safe "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| "Datara" -> ignore (Pretty.fprintf !warn_race "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| "High r" -> ignore (Pretty.fprintf !warn_higr "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| "High w" -> ignore (Pretty.fprintf !warn_higw "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| "Low re" -> ignore (Pretty.fprintf !warn_lowr "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| "Low wr" -> ignore (Pretty.fprintf !warn_loww "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)
| _ -> ()
end;
ignore (Pretty.fprintf !warn_out "%s:\n @[%a@]\n" group_name (docList ~sep:line f) errors)

This works as follows in the HTML output: when you click on a line with a race warning, it lists other warnings in the same group there as well, to indicate which other lines its racing with.

What #255 does is just add an advanced mechanism for printing the warnings on the terminal, but none of that new metadata (certainty, nested category) is reflected in the warnings table for further usage. Therefore HTML, GobView or the Magpie integration (if it were to get the warnings properly as JSON/XML, not by regexing the output) wouldn't be able to use that metadata still.
Moreover, since print_group is a level below the warn* functions, it completely lacks the support for any of the refactored stuff. So grouped warnings cannot have certainty or categories.

Tbh, print_group is a pretty niche feature: it's just used for data race warnings and all over OSEK. Nevertheless, to eventually have one warnings system, it needs to also support that use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cleanup Refactoring, clean-up feature practical-course Practical Course at TUM usability
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants