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