Reviewed By: sblackshear Differential Revision: D3585008 fbshipit-source-id: 64a0bdamaster
parent
d6149c7741
commit
d4a9a6cde1
@ -0,0 +1,61 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2016 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Module for parsing stack traces and using them to guide Infer analysis *)
|
||||||
|
|
||||||
|
module F = Format
|
||||||
|
|
||||||
|
type frame = {
|
||||||
|
class_str : string;
|
||||||
|
method_str : string;
|
||||||
|
file_str : string;
|
||||||
|
line_num : int;
|
||||||
|
}
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
exception_name: string;
|
||||||
|
frames: frame list;
|
||||||
|
}
|
||||||
|
|
||||||
|
let make exception_name frames = { exception_name; frames; }
|
||||||
|
|
||||||
|
let make_frame class_str method_str file_str line_num =
|
||||||
|
{ class_str; method_str; file_str; line_num; }
|
||||||
|
|
||||||
|
let parse_stack_frame frame_str =
|
||||||
|
(* separate the qualified method name and the parenthesized text/line number*)
|
||||||
|
ignore(Str.string_match (Str.regexp "\t*at \\(.*\\)(\\(.*\\))") frame_str 0);
|
||||||
|
let qualified_procname = Str.matched_group 1 frame_str in
|
||||||
|
let file_and_line = Str.matched_group 2 frame_str in
|
||||||
|
(* separate the class name from the method name *)
|
||||||
|
ignore(Str.string_match (Str.regexp "\\(.*\\)\\.\\(.*\\)") qualified_procname 0);
|
||||||
|
let class_str = Str.matched_group 1 qualified_procname in
|
||||||
|
let method_str = Str.matched_group 2 qualified_procname in
|
||||||
|
(* separate the filename and line number *)
|
||||||
|
ignore(Str.string_match (Str.regexp "\\(.*\\):\\([0-9]+\\)") file_and_line 0);
|
||||||
|
let file_str = Str.matched_group 1 file_and_line in
|
||||||
|
let line_num = int_of_string (Str.matched_group 2 file_and_line) in
|
||||||
|
make_frame class_str method_str file_str line_num
|
||||||
|
|
||||||
|
let parse_exception_line exception_line =
|
||||||
|
ignore(Str.string_match
|
||||||
|
(Str.regexp "Exception in thread \"\\(.*\\)\" \\(.*\\)")
|
||||||
|
exception_line
|
||||||
|
0);
|
||||||
|
let exception_name = Str.matched_group 2 exception_line in
|
||||||
|
exception_name
|
||||||
|
|
||||||
|
let of_string s =
|
||||||
|
let lines = Str.split (Str.regexp "\n") s in
|
||||||
|
match lines with
|
||||||
|
| exception_line :: trace ->
|
||||||
|
let exception_name = parse_exception_line exception_line in
|
||||||
|
let parsed = IList.map parse_stack_frame trace in
|
||||||
|
make exception_name parsed
|
||||||
|
| [] -> failwith "Empty stack trace"
|
@ -0,0 +1,28 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2016 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
(** Module for parsing stack traces and using them to guide Infer analysis *)
|
||||||
|
|
||||||
|
type frame = {
|
||||||
|
class_str : string;
|
||||||
|
method_str : string;
|
||||||
|
file_str : string;
|
||||||
|
line_num : int;
|
||||||
|
}
|
||||||
|
|
||||||
|
type t = {
|
||||||
|
exception_name: string;
|
||||||
|
frames: frame list;
|
||||||
|
}
|
||||||
|
|
||||||
|
val make : string -> frame list -> t
|
||||||
|
|
||||||
|
val make_frame : string -> string -> string -> int -> frame
|
||||||
|
|
||||||
|
val of_string : string -> t
|
@ -0,0 +1,73 @@
|
|||||||
|
(*
|
||||||
|
* Copyright (c) 2016 - present Facebook, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the BSD style license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||||||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*)
|
||||||
|
|
||||||
|
open !Utils
|
||||||
|
|
||||||
|
module F = Format
|
||||||
|
|
||||||
|
let tests =
|
||||||
|
let open OUnit2 in
|
||||||
|
|
||||||
|
let empty_string_test =
|
||||||
|
let empty_string_test_ _ =
|
||||||
|
assert_raises
|
||||||
|
(Failure "Empty stack trace")
|
||||||
|
(fun () -> Stacktrace.of_string "") in
|
||||||
|
"empty_string">::empty_string_test_ in
|
||||||
|
|
||||||
|
let empty_trace_test =
|
||||||
|
let empty_stack_trace_s = "Exception in thread \"main\" java.lang.NullPointerException" in
|
||||||
|
let trace = Stacktrace.of_string empty_stack_trace_s in
|
||||||
|
let empty_trace_test_ _ =
|
||||||
|
assert_equal trace.frames [] in
|
||||||
|
"empty_trace">::empty_trace_test_ in
|
||||||
|
|
||||||
|
let one_frame_trace_test =
|
||||||
|
let one_frame_trace_test_s =
|
||||||
|
"Exception in thread \"main\" java.lang.NullPointerException\n" ^
|
||||||
|
"\tat endtoend.java.checkers.crashcontext.MinimalCrashTest.main" ^
|
||||||
|
"(MinimalCrashTest.java:16)" in
|
||||||
|
let trace = Stacktrace.of_string
|
||||||
|
one_frame_trace_test_s in
|
||||||
|
let expected = Stacktrace.make
|
||||||
|
"java.lang.NullPointerException"
|
||||||
|
[Stacktrace.make_frame
|
||||||
|
"endtoend.java.checkers.crashcontext.MinimalCrashTest"
|
||||||
|
"main"
|
||||||
|
"MinimalCrashTest.java"
|
||||||
|
16] in
|
||||||
|
let one_frame_trace_test_ _ =
|
||||||
|
assert_equal trace expected in
|
||||||
|
"one_frame_trace">::one_frame_trace_test_ in
|
||||||
|
|
||||||
|
let multi_frame_trace_test =
|
||||||
|
let multi_frame_trace_test_s =
|
||||||
|
"Exception in thread \"main\" java.lang.NullPointerException\n\t" ^
|
||||||
|
"at endtoend.java.checkers.crashcontext.MultiStackFrameCrashTest.bar" ^
|
||||||
|
"(MultiStackFrameCrashTest.java:16)\n" ^
|
||||||
|
"\tat endtoend.java.checkers.crashcontext.MultiStackFrameCrashTest.foo" ^
|
||||||
|
"(MultiStackFrameCrashTest.java:20)\n" ^
|
||||||
|
"\tat endtoend.java.checkers.crashcontext.MultiStackFrameCrashTest.main" ^
|
||||||
|
"(MultiStackFrameCrashTest.java:24)" in
|
||||||
|
let trace = Stacktrace.of_string
|
||||||
|
multi_frame_trace_test_s in
|
||||||
|
let class_name =
|
||||||
|
"endtoend.java.checkers.crashcontext.MultiStackFrameCrashTest" in
|
||||||
|
let file_name = "MultiStackFrameCrashTest.java" in
|
||||||
|
let expected = Stacktrace.make
|
||||||
|
"java.lang.NullPointerException"
|
||||||
|
[Stacktrace.make_frame class_name "bar" file_name 16;
|
||||||
|
Stacktrace.make_frame class_name "foo" file_name 20;
|
||||||
|
Stacktrace.make_frame class_name "main" file_name 24] in
|
||||||
|
let multi_frame_trace_test_ _ =
|
||||||
|
assert_equal trace expected in
|
||||||
|
"multi_frame_trace_test">::multi_frame_trace_test_ in
|
||||||
|
|
||||||
|
"all_tests_suite">:::[empty_string_test; empty_trace_test;
|
||||||
|
one_frame_trace_test; multi_frame_trace_test]
|
Loading…
Reference in new issue