#ifndef NSAN_STATS_H
#define NSAN_STATS_H
#include "sanitizer_common/sanitizer_addrhashmap.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_mutex.h"
namespace __nsan {
enum class CheckTypeT {
kUnknown = 0,
kRet,
kArg,
kLoad,
kStore,
kInsert,
kUser,
kFcmp,
kMaxCheckType,
};
class Stats {
public:
Stats();
~Stats();
void AddCheck(CheckTypeT check_ty, __sanitizer::uptr pc, __sanitizer::uptr bp,
double rel_err);
void AddWarning(CheckTypeT check_ty, __sanitizer::uptr pc,
__sanitizer::uptr bp, double rel_err);
void AddInvalidLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);
void AddUnknownLoadTrackingEvent(__sanitizer::uptr pc, __sanitizer::uptr bp);
void Print() const;
private:
using IndexMap = __sanitizer::AddrHashMap<__sanitizer::uptr, 11>;
struct CheckAndWarningsValue {
CheckTypeT check_ty;
__sanitizer::u32 stack_id = 0;
__sanitizer::u64 num_checks = 0;
__sanitizer::u64 num_warnings = 0;
double max_relative_err = 0;
};
IndexMap CheckAndWarningsMap;
__sanitizer::InternalMmapVectorNoCtor<CheckAndWarningsValue>
check_and_warnings;
mutable __sanitizer::Mutex check_and_warning_mutex;
struct LoadTrackingValue {
CheckTypeT check_ty;
__sanitizer::u32 stack_id = 0;
__sanitizer::u64 num_invalid = 0;
__sanitizer::u64 num_unknown = 0;
};
IndexMap LoadTrackingMap;
__sanitizer::InternalMmapVectorNoCtor<LoadTrackingValue> TrackedLoads;
mutable __sanitizer::Mutex TrackedLoadsMutex;
};
extern Stats *nsan_stats;
void InitializeStats();
}
#endif