[DB] Don't fail hard when realpath fails

Summary: When infer runs on preprocessed source, original files may not be around anymore. Don't crash infer when that happens.

Reviewed By: jvillard, jberdine

Differential Revision: D4258285

fbshipit-source-id: a19569c
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent ff3b6a10db
commit bd0f0cc7fc

@ -171,10 +171,8 @@ def _text_of_report_list(project_root, reports, bugs_txt_path, limit=None,
def _is_user_visible(project_root, report):
filename = report[JSON_INDEX_FILENAME]
kind = report[JSON_INDEX_KIND]
return (os.path.isfile(os.path.join(project_root, filename)) and
kind in [ISSUE_KIND_ERROR, ISSUE_KIND_WARNING, ISSUE_KIND_ADVICE])
return kind in [ISSUE_KIND_ERROR, ISSUE_KIND_WARNING, ISSUE_KIND_ADVICE]
def print_and_save_errors(infer_out, project_root, json_report, bugs_out,

@ -11,6 +11,7 @@ from __future__ import print_function
from __future__ import unicode_literals
import codecs
import os
from . import colorize, config
@ -67,6 +68,8 @@ def build_source_context(source_name, mode, report_line):
# get source excerpt
line_number = 1
excerpt = ''
if not os.path.isfile(source_name):
return ''
with codecs.open(source_name, 'r',
encoding=config.CODESET, errors="replace") as source_file:
# avoid going past the end of the file

@ -386,13 +386,6 @@ let should_report (issue_kind: Exceptions.err_kind) issue_type error_desc =>
}
};
let is_file source_file =>
switch (Unix.stat (DB.source_file_to_abs_path source_file)) {
| {st_kind: S_REG | S_LNK} => true
| _ => false
| exception Unix.Unix_error _ => false
};
let module IssuesCsv = {
let csv_issues_id = ref 0;
let pp_header fmt () =>
@ -427,8 +420,7 @@ let module IssuesCsv = {
};
if (
in_footprint &&
error_filter source_file error_desc error_name &&
should_report ekind error_name error_desc && is_file source_file
error_filter source_file error_desc error_name && should_report ekind error_name error_desc
) {
let err_desc_string = error_desc_to_csv_string error_desc;
let err_advice_string = error_advice_to_csv_string error_desc;
@ -504,8 +496,7 @@ let module IssuesJson = {
if (
in_footprint &&
error_filter source_file error_desc error_name &&
should_report_source_file &&
should_report ekind error_name error_desc && is_file source_file
should_report_source_file && should_report ekind error_name error_desc
) {
let kind = Exceptions.err_kind_string ekind;
let bug_type = Localise.to_string error_name;
@ -826,8 +817,7 @@ let module Stats = {
let error_strs = {
let pp1 fmt () => F.fprintf fmt "%d: %s" stats.nerrors type_str;
let pp2 fmt () =>
F.fprintf
fmt " %a:%d" DB.source_file_pp loc.Location.file loc.Location.line;
F.fprintf fmt " %a:%d" DB.source_file_pp loc.Location.file loc.Location.line;
let pp3 fmt () => F.fprintf fmt " (%a)" Localise.pp_error_desc error_desc;
[pp_to_string pp1 (), pp_to_string pp2 (), pp_to_string pp3 ()]
};

@ -48,14 +48,14 @@ let rel_path_from_abs_path root fname =
else None (* The project root is not a prefix of the file name *)
let source_file_from_abs_path fname =
(* IMPORTANT: results of realpath are cached to not ruin performance *)
let fname_real = realpath fname in
let project_root_real = realpath Config.project_root in
let models_dir_real = Config.models_src_dir in
if Filename.is_relative fname then
(failwithf
"ERROR: Path %s is relative, when absolute path was expected .@."
fname);
(* try to get realpath of source file. Use original if it fails *)
let fname_real = try realpath fname with Unix.Unix_error _ -> fname in
let project_root_real = realpath Config.project_root in
let models_dir_real = Config.models_src_dir in
match rel_path_from_abs_path project_root_real fname_real with
| Some path -> RelativeProjectRoot path
| None -> (

@ -600,8 +600,19 @@ let rec create_path path =
let realpath_cache = Hashtbl.create 1023
let realpath path =
try Hashtbl.find realpath_cache path
with Not_found ->
let realpath = Core.Std.Filename.realpath path in
Hashtbl.add realpath_cache path realpath;
realpath
match Hashtbl.find realpath_cache path with
| exception Not_found -> (
match Core.Std.Filename.realpath path with
| realpath ->
Hashtbl.add realpath_cache path (Ok realpath);
realpath
| exception Unix.Unix_error (code, f, arg) ->
F.eprintf
"WARNING: Failed to resolve file %s with \"%s\" \n@." arg (Unix.error_message code);
(* cache failures as well *)
Hashtbl.add realpath_cache path (Error (code, f, arg));
raise (Unix.Unix_error (code, f, arg))
)
| Ok path -> path
| Error (code, f, arg) -> raise (Unix.Unix_error (code, f, arg))

@ -0,0 +1,16 @@
# 1 "/tmp/removed_src.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 330 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "/tmp/removed_src.c" 2
# 1 "/tmp/removed_header.h" 1
void fun();
# 3 "/tmp/removed_src.c" 2
int deref(int* a) { return *a; }
int test() { return deref(0); }

@ -0,0 +1,18 @@
# 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.
TESTS_DIR = ../..
ANALYZER = infer
CLANG_OPTIONS = -c
INFER_OPTIONS = --report-custom-error --developer-mode --headers --project-root ../codetoanalyze
INFERPRINT_OPTIONS = --issues-tests
SOURCES = \
../codetoanalyze/preprocessed.c
include $(TESTS_DIR)/clang.make

@ -0,0 +1 @@
/tmp/removed_src.c, test, 0, NULL_DEREFERENCE, [start of procedure test(),start of procedure deref()]
Loading…
Cancel
Save