Skip to content

Commit f4d5a45

Browse files
committed
Merge branch 'master' into issue-1192
2 parents 24b6664 + 24e33cc commit f4d5a45

File tree

100 files changed

+996
-746
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+996
-746
lines changed

.git-blame-ignore-revs

+3
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,6 @@ ec8611a3a72ae0d95ec82ffee16c5c4785111aa1
3131

3232
# fix indentation in baseInvariant
3333
f3ffd5e45c034574020f56519ccdb021da2a1479
34+
35+
# Fix indentation in various non-legacy code
36+
c3e2cc848479ae86de5542b6ab0e75a74e9cf8c9

.semgrep/logs.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
rules:
2+
- id: print-not-logging
3+
pattern-either:
4+
- pattern: printf
5+
- pattern: Printf.printf
6+
- pattern: BatPrintf.printf
7+
- pattern: Format.printf
8+
- pattern: Pretty.printf
9+
10+
- pattern: eprintf
11+
- pattern: Printf.eprintf
12+
- pattern: BatPrintf.eprintf
13+
- pattern: Format.eprintf
14+
- pattern: Pretty.eprintf
15+
16+
- pattern: print_endline
17+
- pattern: prerr_endline
18+
- pattern: print_string
19+
paths:
20+
exclude:
21+
- logs.ml
22+
- bench/
23+
message: printing should be replaced with logging
24+
languages: [ocaml]
25+
severity: WARNING
26+
27+
- id: print-newline-not-logging
28+
pattern-either:
29+
- pattern: print_newline
30+
- pattern: prerr_newline
31+
paths:
32+
exclude:
33+
- logs.ml
34+
- bench/
35+
fix: Logs.newline
36+
message: use Logs instead
37+
languages: [ocaml]
38+
severity: WARNING

conf/incremental.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"earlyglobs": true
2525
},
2626
"dbg": {
27-
"verbose": true,
27+
"level": "debug",
2828
"trace": {
2929
"context": true
3030
},

conf/minimal_incremental.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"earlyglobs": true
2424
},
2525
"dbg": {
26-
"verbose": true,
26+
"level": "debug",
2727
"trace": {
2828
"context": true
2929
},

docs/developer-guide/debugging.md

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,46 @@
11
# Debugging
22

3-
## Printing
4-
Goblint extensively uses [CIL's `Pretty`](https://people.eecs.berkeley.edu/~necula/cil/api/Pretty.html) module for printing due to many non-primitive values.
3+
## Logging
4+
Instead of debug printing directly to `stdout`, all logging should be done using the `Logs` module.
5+
This allows for consistent pretty terminal output, as well as avoiding interference with server mode.
6+
There are five logging levels: result, error, warning, info and debug.
7+
Log output is controlled by the `dbg.level` option, which defaults to "info".
58

6-
* Printing CIL values (e.g. an expression `exp`) using the corresponding pretty-printer `d_exp` from `Cil` module:
9+
Logs are written to `stderr`, except for result level, which go to `stdout` by default.
10+
11+
Goblint extensively uses [CIL's `Pretty`](https://people.eecs.berkeley.edu/~necula/cil/api/Pretty.html) module for output due to many non-primitive values.
12+
13+
* Logging CIL values (e.g. an expression `exp`) using the corresponding pretty-printer `d_exp` from `Cil` module:
714

815
```ocaml
9-
ignore (Pretty.printf "A CIL exp: %a\n" d_exp exp);
16+
Logs.debug "A CIL exp: %a\n" d_exp exp;
1017
```
1118

12-
* Printing Goblint's `Printable` values (e.g. a domain `D` element `d`) using the corresponding pretty-printer `D.pretty`:
19+
* Logging Goblint's `Printable` values (e.g. a domain `D` element `d`) using the corresponding pretty-printer `D.pretty`:
1320

1421
```ocaml
15-
ignore (Pretty.printf "A domain element: %a\n" D.pretty d);
22+
Logs.debug "A domain element: %a\n" D.pretty d;
1623
```
1724

18-
* Printing primitives (e.g. OCaml ints, strings, etc) using the standard [OCaml `Printf`](https://ocaml.org/api/Printf.html) specifiers:
25+
* Logging primitives (e.g. OCaml ints, strings, etc) using the standard [OCaml `Printf`](https://ocaml.org/api/Printf.html) specifiers:
1926

2027
```ocaml
21-
ignore (Pretty.printf "An int and a string: %d %s\n" 42 "magic");
28+
Logs.debug "An int and a string: %d %s\n" 42 "magic";
2229
```
2330

24-
* Printing lists of pretty-printables (e.g. expressions list `exps`) using `d_list`:
31+
* Logging lists of pretty-printables (e.g. expressions list `exps`) using `d_list`:
2532

2633
```ocaml
27-
ignore (Pretty.printf "Some expressions: %a\n" (d_list ", " d_exp) exps);
34+
Logs.debug "Some expressions: %a\n" (d_list ", " d_exp) exps;
2835
```
2936

3037

3138
## Tracing
32-
Tracing is a nicer alternative to debug printing, because it can be disabled for best performance and it can be used to only see relevant tracing output.
39+
Tracing is a nicer alternative to some logging, because it can be disabled for best performance and it can be used to only see relevant tracing output.
3340

3441
Recompile with tracing enabled: `./scripts/trace_on.sh`.
3542

36-
Instead of debug printing use a tracing function from the `Messages` module, which is often aliased to just `M` (and pick a relevant name instead of `mything`):
43+
Instead of logging use a tracing function from the `Messages` module, which is often aliased to just `M` (and pick a relevant name instead of `mything`):
3744
```ocaml
3845
if M.tracing then M.trace "mything" "A domain element: %a\n" D.pretty d;
3946
```

docs/developer-guide/messaging.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Messaging
22

3-
The message system in `Messages` module should be used for outputting all (non-[tracing](./debugging.md#tracing)) information instead of printing them directly to `stdout`.
3+
The message system in `Messages` module should be used for outputting all analysis results of the program to the user, instead of printing them directly to `stdout`.
44
This allows for consistent pretty terminal output, as well as export to Goblint result viewers and IDEs.
5+
For other kinds of (debug) output, see [Debugging](./debugging.md).
56

67
## Message structure
78

goblint.opam

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ dev-repo: "git+https://github.com/goblint/analyzer.git"
7777
available: os-distribution != "alpine" & arch != "arm64"
7878
pin-depends: [
7979
# published goblint-cil 2.0.3 is currently up-to-date, so no pin needed
80-
# [ "goblint-cil.2.0.3" "git+https://github.com/goblint/cil.git#d2760bacfbfdb25a374254de44f2ff1cb5f42abd" ]
80+
[ "goblint-cil.2.0.3" "git+https://github.com/goblint/cil.git#3cb720fe333289aca998d67bd210c57a87248c51" ]
8181
# TODO: add back after release, only pinned for optimization (https://github.com/ocaml-ppx/ppx_deriving/pull/252)
8282
[ "ppx_deriving.5.2.1" "git+https://github.com/ocaml-ppx/ppx_deriving.git#0a89b619f94cbbfc3b0fb3255ab4fe5bc77d32d6" ]
8383
]

goblint.opam.locked

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ post-messages: [
131131
]
132132
# TODO: manually reordered to avoid opam pin crash: https://github.com/ocaml/opam/issues/4936
133133
pin-depends: [
134+
[
135+
"goblint-cil.2.0.3"
136+
"git+https://github.com/goblint/cil.git#3cb720fe333289aca998d67bd210c57a87248c51"
137+
]
134138
[
135139
"ppx_deriving.5.2.1"
136140
"git+https://github.com/ocaml-ppx/ppx_deriving.git#0a89b619f94cbbfc3b0fb3255ab4fe5bc77d32d6"

goblint.opam.template

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
available: os-distribution != "alpine" & arch != "arm64"
44
pin-depends: [
55
# published goblint-cil 2.0.3 is currently up-to-date, so no pin needed
6-
# [ "goblint-cil.2.0.3" "git+https://github.com/goblint/cil.git#d2760bacfbfdb25a374254de44f2ff1cb5f42abd" ]
6+
[ "goblint-cil.2.0.3" "git+https://github.com/goblint/cil.git#3cb720fe333289aca998d67bd210c57a87248c51" ]
77
# TODO: add back after release, only pinned for optimization (https://github.com/ocaml-ppx/ppx_deriving/pull/252)
88
[ "ppx_deriving.5.2.1" "git+https://github.com/ocaml-ppx/ppx_deriving.git#0a89b619f94cbbfc3b0fb3255ab4fe5bc77d32d6" ]
99
]

src/analyses/apron/relationAnalysis.apron.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,7 @@ struct
761761
let finalize () =
762762
let file = GobConfig.get_string "exp.relation.prec-dump" in
763763
if file <> "" then begin
764-
Printf.printf "exp.relation.prec-dump is potentially costly (for domains other than octagons), do not use for performance data!\n";
764+
Logs.warn "exp.relation.prec-dump is potentially costly (for domains other than octagons), do not use for performance data!";
765765
Timing.wrap "relation.prec-dump" store_data (Fpath.v file)
766766
end;
767767
Priv.finalize ()

src/analyses/base.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ struct
10201020
match ofs with
10211021
| NoOffset -> `NoOffset
10221022
| Field (fld, ofs) -> `Field (fld, convert_offset ~ctx st ofs)
1023-
| Index (exp, ofs) when CilType.Exp.equal exp Offset.Index.Exp.any -> (* special offset added by convertToQueryLval *)
1023+
| Index (exp, ofs) when CilType.Exp.equal exp (Lazy.force Offset.Index.Exp.any) -> (* special offset added by convertToQueryLval *)
10241024
`Index (IdxDom.top (), convert_offset ~ctx st ofs)
10251025
| Index (exp, ofs) ->
10261026
match eval_rv ~ctx st exp with
@@ -2347,7 +2347,7 @@ struct
23472347
| CArrays.IsNotSubstr -> Address (AD.null_ptr)
23482348
| CArrays.IsSubstrAtIndex0 -> Address (eval_lv ~ctx st (mkMem ~addr:(Cil.stripCasts haystack) ~off:NoOffset))
23492349
| CArrays.IsMaybeSubstr -> Address (AD.join (eval_lv ~ctx st
2350-
(mkMem ~addr:(Cil.stripCasts haystack) ~off:(Index (Offset.Index.Exp.any, NoOffset)))) (AD.null_ptr)))
2350+
(mkMem ~addr:(Cil.stripCasts haystack) ~off:(Index (Lazy.force Offset.Index.Exp.any, NoOffset)))) (AD.null_ptr)))
23512351
| None -> st
23522352
end
23532353
| Strcmp { s1; s2; n }, _ ->

src/analyses/basePriv.ml

+4-4
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ struct
230230
CPA.find x st.cpa
231231
(* let read_global ask getg cpa x =
232232
let (cpa', v) as r = read_global ask getg cpa x in
233-
ignore (Pretty.printf "READ GLOBAL %a (%a, %B) = %a\n" CilType.Varinfo.pretty x CilType.Location.pretty !Goblint_tracing.current_loc (is_unprotected ask x) VD.pretty v);
233+
Logs.debug "READ GLOBAL %a (%a, %B) = %a" CilType.Varinfo.pretty x CilType.Location.pretty !Goblint_tracing.current_loc (is_unprotected ask x) VD.pretty v;
234234
r *)
235235
let write_global ?(invariant=false) ask getg sideg (st: BaseComponents (D).t) x v =
236236
let cpa' = CPA.add x v st.cpa in
@@ -240,7 +240,7 @@ struct
240240
{st with cpa = cpa'}
241241
(* let write_global ask getg sideg cpa x v =
242242
let cpa' = write_global ask getg sideg cpa x v in
243-
ignore (Pretty.printf "WRITE GLOBAL %a %a = %a\n" CilType.Varinfo.pretty x VD.pretty v CPA.pretty cpa');
243+
Logs.debug "WRITE GLOBAL %a %a = %a" CilType.Varinfo.pretty x VD.pretty v CPA.pretty cpa';
244244
cpa' *)
245245

246246
let lock ask getg (st: BaseComponents (D).t) m =
@@ -335,7 +335,7 @@ struct
335335
{st with cpa = cpa'}
336336
(* let write_global ask getg sideg cpa x v =
337337
let cpa' = write_global ask getg sideg cpa x v in
338-
ignore (Pretty.printf "WRITE GLOBAL %a %a = %a\n" CilType.Varinfo.pretty x VD.pretty v CPA.pretty cpa');
338+
Logs.debug "WRITE GLOBAL %a %a = %a" CilType.Varinfo.pretty x VD.pretty v CPA.pretty cpa';
339339
cpa' *)
340340

341341
let lock (ask: Queries.ask) getg (st: BaseComponents (D).t) m =
@@ -1657,7 +1657,7 @@ struct
16571657
let dump () =
16581658
let f = open_out_bin (get_string "exp.priv-prec-dump") in
16591659
(* LVH.iter (fun (l, x) v ->
1660-
ignore (Pretty.printf "%a %a = %a\n" CilType.Location.pretty l CilType.Varinfo.pretty x VD.pretty v)
1660+
Logs.debug "%a %a = %a" CilType.Location.pretty l CilType.Varinfo.pretty x VD.pretty v
16611661
) lvh; *)
16621662
Marshal.output f ({name = get_string "ana.base.privatization"; results = lvh}: result);
16631663
close_out_noerr f

src/analyses/extractPthread.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ module Codegen = struct
576576
let dir = GobSys.mkdir_or_exists_absolute (Fpath.v "pml-result") in
577577
let path = Fpath.to_string @@ Fpath.append dir (Fpath.v ("pthread." ^ ext)) in
578578
output_file ~filename:path ~text:content ;
579-
print_endline @@ "saved " ^ desc ^ " as " ^ path
579+
Logs.info "saved %s as %s" desc path
580580
end
581581

582582
let tabulate = ( ^ ) "\t"
@@ -612,7 +612,7 @@ module Codegen = struct
612612
let called_funs_done = ref Set.empty in
613613

614614
let rec process_def res =
615-
print_endline @@ Resource.show res ;
615+
print_endline @@ Resource.show res ; (* nosemgrep: print-not-logging *)
616616
let res_type = Resource.res_type res in
617617
let res_name = Resource.res_name res in
618618
let is_thread = res_type = Resource.Thread in
@@ -850,7 +850,7 @@ module Codegen = struct
850850

851851
Writer.write "promela model" "pml" promela ;
852852
Writer.write "graph" "dot" dot_graph ;
853-
print_endline
853+
Logs.result
854854
"Copy spin/pthread_base.pml to same folder and then do: spin -a \
855855
pthread.pml && cc -o pan pan.c && ./pan -a"
856856
end

src/analyses/mCP.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ struct
5858
let y = find_id yn in
5959
if not (exists (fun (y',_) -> y=y') xs) then begin
6060
let xn = find_spec_name x in
61-
Legacy.Printf.eprintf "Activated analysis '%s' depends on '%s' and '%s' is not activated.\n" xn yn yn;
61+
Logs.error "Activated analysis '%s' depends on '%s' and '%s' is not activated.\n" xn yn yn;
6262
raise Stdlib.Exit
6363
end
6464
in

src/analyses/memOutOfBounds.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ struct
171171
match ofs with
172172
| NoOffset -> `NoOffset
173173
| Field (fld, ofs) -> `Field (fld, convert_offset ofs)
174-
| Index (exp, ofs) when CilType.Exp.equal exp Offset.Index.Exp.any -> (* special offset added by convertToQueryLval *)
174+
| Index (exp, ofs) when CilType.Exp.equal exp (Lazy.force Offset.Index.Exp.any) -> (* special offset added by convertToQueryLval *)
175175
`Index (ID.top (), convert_offset ofs)
176176
| Index (exp, ofs) ->
177177
let i = match ctx.ask (Queries.EvalInt exp) with

src/analyses/raceAnalysis.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ struct
269269
let g: V.t = Obj.obj g in
270270
begin match g with
271271
| `Left g' -> (* accesses *)
272-
(* ignore (Pretty.printf "WarnGlobal %a\n" Access.MemoRoot.pretty g'); *)
272+
(* Logs.debug "WarnGlobal %a" Access.MemoRoot.pretty g'; *)
273273
let trie = G.access (ctx.global g) in
274274
(** Distribute access to contained fields. *)
275275
let rec distribute_inner offset (accs, children) ~prefix ~type_suffix_prefix =

src/analyses/threadId.ml

+3-6
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,9 @@ struct
175175
let non_uniques = List.filter_map (fun (a,b) -> if not (Thread.is_unique a) then Some a else None) tids in
176176
let uc = List.length uniques in
177177
let nc = List.length non_uniques in
178-
Printf.printf "Encountered number of thread IDs (unique): %i (%i)\n" (uc+nc) uc;
179-
Printf.printf "unique: ";
180-
List.iter (fun tid -> Printf.printf " %s " (Thread.show tid)) uniques;
181-
Printf.printf "\nnon-unique: ";
182-
List.iter (fun tid -> Printf.printf " %s " (Thread.show tid)) non_uniques;
183-
Printf.printf "\n"
178+
M.debug_noloc ~category:Analyzer "Encountered number of thread IDs (unique): %i (%i)" (uc+nc) uc;
179+
M.msg_group Debug ~category:Analyzer "Unique TIDs" (List.map (fun tid -> (Thread.pretty () tid, None)) uniques);
180+
M.msg_group Debug ~category:Analyzer "Non-unique TIDs" (List.map (fun tid -> (Thread.pretty () tid, None)) non_uniques)
184181

185182
let finalize () =
186183
if GobConfig.get_bool "dbg.print_tids" then print_tid_info ();

0 commit comments

Comments
 (0)