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