846
850
static Int get_char ( Int fd, Char* out_buf )
853
static Char buf[256];
850
854
static Int buf_size = 0;
851
855
static Int buf_used = 0;
852
vg_assert(buf_size >= 0 && buf_size <= 64);
856
vg_assert(buf_size >= 0 && buf_size <= 256);
853
857
vg_assert(buf_used >= 0 && buf_used <= buf_size);
854
858
if (buf_used == buf_size) {
855
r = VG_(read)(fd, buf, 64);
859
r = VG_(read)(fd, buf, 256);
856
860
if (r < 0) return r; /* read failed */
857
vg_assert(r >= 0 && r <= 64);
861
vg_assert(r >= 0 && r <= 256);
861
865
if (buf_size == 0)
862
866
return 0; /* eof */
863
vg_assert(buf_size >= 0 && buf_size <= 64);
867
vg_assert(buf_size >= 0 && buf_size <= 256);
864
868
vg_assert(buf_used >= 0 && buf_used < buf_size);
865
869
*out_buf = buf[buf_used];
989
999
supp->string = supp->extra = NULL;
991
1001
eof = VG_(get_line) ( fd, buf, N_BUF );
994
1005
if (!VG_STREQ(buf, "{")) BOMB("expected '{' or end-of-file");
996
1007
eof = VG_(get_line) ( fd, buf, N_BUF );
998
1010
if (eof || VG_STREQ(buf, "}")) BOMB("unexpected '}'");
1000
supp->sname = VG_(arena_strdup)(VG_AR_CORE, buf);
1012
supp->sname = VG_(arena_strdup)(VG_AR_CORE, "errormgr.losf.2", buf);
1002
1014
eof = VG_(get_line) ( fd, buf, N_BUF );
1004
1017
if (eof) BOMB("unexpected end-of-file");
1048
1062
if (VG_(needs).tool_errors &&
1049
!VG_TDICT_CALL(tool_read_extra_suppression_info, fd, buf, N_BUF, supp))
1063
!VG_TDICT_CALL(tool_read_extra_suppression_info,
1064
fd, buf, N_BUF, supp))
1051
1066
BOMB("bad or missing extra suppression info");
1069
/* the main frame-descriptor reading loop */
1056
1072
eof = VG_(get_line) ( fd, buf, N_BUF );
1058
1075
BOMB("unexpected end-of-file");
1059
1076
if (VG_STREQ(buf, "}")) {
1078
1097
if (!VG_STREQ(buf, "}")) {
1080
1099
eof = VG_(get_line) ( fd, buf, N_BUF );
1081
1101
} while (!eof && !VG_STREQ(buf, "}"));
1104
// Reject entries which are entirely composed of frame
1106
vg_assert(i > 0); // guaranteed by frame-descriptor reading loop
1107
for (j = 0; j < i; j++) {
1108
if (tmp_callers[j].ty == FunName || tmp_callers[j].ty == ObjName)
1110
vg_assert(tmp_callers[j].ty == DotDotDot);
1112
vg_assert(j >= 0 && j <= i);
1114
// we didn't find any non-"..." entries
1115
BOMB("suppression must contain at least one location "
1116
"line which is not \"...\"");
1084
1119
// Copy tmp_callers[] into supp->callers[]
1085
1120
supp->n_callers = i;
1086
supp->callers = VG_(arena_malloc)(VG_AR_CORE, i*sizeof(SuppLoc));
1121
supp->callers = VG_(arena_malloc)(VG_AR_CORE, "errormgr.losf.4",
1087
1123
for (i = 0; i < supp->n_callers; i++) {
1088
1124
supp->callers[i] = tmp_callers[i];
1165
/*------------------------------------------------------------*/
1166
/*--- Matching errors to suppressions ---*/
1167
/*------------------------------------------------------------*/
1169
/* Parameterising functions for the use of VG_(generic_match) in
1170
suppression-vs-error matching. The suppression frames (SuppLoc)
1171
play the role of 'pattern'-element, and the error frames (IPs,
1172
hence simply Addrs) play the role of 'input'. In short then, we're
1173
matching a sequence of Addrs against a pattern composed of a
1174
sequence of SuppLocs.
1176
static Bool supploc_IsStar ( void* supplocV )
1178
SuppLoc* supploc = (SuppLoc*)supplocV;
1179
return supploc->ty == DotDotDot;
1182
static Bool supploc_IsQuery ( void* supplocV )
1184
return False; /* there's no '?' equivalent in the supp syntax */
1187
static Bool supp_pattEQinp ( void* supplocV, void* addrV )
1189
SuppLoc* supploc = (SuppLoc*)supplocV; /* PATTERN */
1190
Addr ip = *(Addr*)addrV; /* INPUT */
1192
Char caller_name[ERRTXT_LEN];
1195
/* So, does this IP address match this suppression-line? */
1196
switch (supploc->ty) {
1198
/* supp_pattEQinp is a callback from VG_(generic_match). As
1199
per the spec thereof (see include/pub_tool_seqmatch.h), we
1200
should never get called with a pattern value for which the
1201
_IsStar or _IsQuery function would return True. Hence
1202
this can't happen. */
1205
/* Get the object name into 'caller_name', or "???"
1207
if (!VG_(get_objname)(ip, caller_name, ERRTXT_LEN))
1208
VG_(strcpy)(caller_name, "???");
1211
/* Get the function name into 'caller_name', or "???"
1213
// Nb: mangled names used in suppressions. Do, though,
1214
// Z-demangle them, since otherwise it's possible to wind
1215
// up comparing "malloc" in the suppression against
1216
// "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
1217
// two of them need to be made to match.
1218
if (!VG_(get_fnname_Z_demangle_only)(ip, caller_name, ERRTXT_LEN))
1219
VG_(strcpy)(caller_name, "???");
1225
/* So now we have the function or object name in caller_name, and
1226
the pattern (at the character level) to match against is in
1227
supploc->name. Hence (and leading to a re-entrant call of
1228
VG_(generic_match)): */
1229
return VG_(string_match)(supploc->name, caller_name);
1232
/////////////////////////////////////////////////////
1234
static Bool supp_matches_callers(Error* err, Supp* su)
1236
/* Unwrap the args and set up the correct parameterisation of
1237
VG_(generic_match), using supploc_IsStar, supploc_IsQuery and
1239
/* note, StackTrace === Addr* */
1240
StackTrace ips = VG_(get_ExeContext_StackTrace)(err->where);
1241
UWord n_ips = VG_(get_ExeContext_n_ips)(err->where);
1242
SuppLoc* supps = su->callers;
1243
UWord n_supps = su->n_callers;
1244
UWord szbPatt = sizeof(SuppLoc);
1245
UWord szbInput = sizeof(Addr);
1246
Bool matchAll = False; /* we just want to match a prefix */
1250
/*PATT*/supps, szbPatt, n_supps, 0/*initial Ix*/,
1251
/*INPUT*/ips, szbInput, n_ips, 0/*initial Ix*/,
1252
supploc_IsStar, supploc_IsQuery, supp_pattEQinp
1256
/////////////////////////////////////////////////////
1126
1259
Bool supp_matches_error(Supp* su, Error* err)
1146
Bool supp_matches_callers(Error* err, Supp* su)
1149
Char caller_name[ERRTXT_LEN];
1150
StackTrace ips = VG_(extract_StackTrace)(err->where);
1152
for (i = 0; i < su->n_callers; i++) {
1154
vg_assert(su->callers[i].name != NULL);
1155
// The string to be used in the unknown case ("???") can be anything
1156
// that couldn't be a valid function or objname. --gen-suppressions
1157
// prints 'obj:*' for such an entry, which will match any string we
1159
switch (su->callers[i].ty) {
1161
if (!VG_(get_objname)(a, caller_name, ERRTXT_LEN))
1162
VG_(strcpy)(caller_name, "???");
1166
// Nb: mangled names used in suppressions. Do, though,
1167
// Z-demangle them, since otherwise it's possible to wind
1168
// up comparing "malloc" in the suppression against
1169
// "_vgrZU_libcZdsoZa_malloc" in the backtrace, and the
1170
// two of them need to be made to match.
1171
if (!VG_(get_fnname_Z_demangle_only)(a, caller_name, ERRTXT_LEN))
1172
VG_(strcpy)(caller_name, "???");
1174
default: VG_(tool_panic)("supp_matches_callers");
1176
if (0) VG_(printf)("cmp %s %s\n", su->callers[i].name, caller_name);
1177
if (!VG_(string_match)(su->callers[i].name, caller_name))
1181
/* If we reach here, it's a match */
1278
/////////////////////////////////////////////////////
1185
1280
/* Does an error context match a suppression? ie is this a suppressible
1186
1281
error? If so, return a pointer to the Supp record, otherwise NULL.
1219
1314
void VG_(print_errormgr_stats) ( void )
1221
1316
VG_(message)(Vg_DebugMsg,
1222
" errormgr: %,lu supplist searches, %,lu comparisons during search",
1317
" errormgr: %'lu supplist searches, %'lu comparisons during search",
1223
1318
em_supplist_searches, em_supplist_cmps
1225
1320
VG_(message)(Vg_DebugMsg,
1226
" errormgr: %,lu errlist searches, %,lu comparisons during search",
1321
" errormgr: %'lu errlist searches, %'lu comparisons during search",
1227
1322
em_errlist_searches, em_errlist_cmps