Add initial stack trace parsing code for semantic blame

Reviewed By: sblackshear

Differential Revision: D3585008

fbshipit-source-id: 64a0bda
master
Lázaro Clapp Jiménez Labora 8 years ago committed by Facebook Github Bot 0
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

@ -23,6 +23,7 @@ let () =
LivenessTests.tests; LivenessTests.tests;
SchedulerTests.tests; SchedulerTests.tests;
BoundedCallTreeTests.tests; BoundedCallTreeTests.tests;
StacktraceTests.tests;
] in ] in
let test_suite = "all" >::: tests in let test_suite = "all" >::: tests in
OUnit2.run_test_tt_main test_suite OUnit2.run_test_tt_main test_suite

@ -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…
Cancel
Save