guaranteed to only happen once. This avoids all the recording and
comparing stuff. But they can be suppressed; returns True if it is
suppressed. Bool 'print_error' dictates whether to print the error.
+ Bool 'count_error' dictates whether to count the error in n_errs_found.
*/
Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind, Addr a, Char* s,
void* extra, ExeContext* where, Bool print_error,
- Bool allow_db_attach )
+ Bool allow_db_attach, Bool count_error )
{
Error err;
Supp *su;
su = is_suppressible_error(&err);
if (NULL == su) {
- n_errs_found++;
+ if (count_error)
+ n_errs_found++;
if (print_error) {
/* A bit of prettyprinting, to ensure there's a blank line
extern Bool VG_(unique_error) ( ThreadId tid, ErrorKind ekind,
Addr a, Char* s, void* extra,
ExeContext* where, Bool print_error,
- Bool allow_GDB_attach );
+ Bool allow_GDB_attach, Bool count_error );
/* Gets a non-blank, non-comment line from fd. bufpp is a pointer to a
pointer to a buffer that must be allocated with VG_(malloc); nBufp is a
Bool MC_(record_leak_error) ( ThreadId tid, UInt n_this_record,
UInt n_total_records, LossRecord* lr,
- Bool print_record )
+ Bool print_record, Bool count_error )
{
MC_Error extra;
extra.Err.Leak.n_this_record = n_this_record;
return
VG_(unique_error) ( tid, Err_Leak, /*Addr*/0, /*s*/NULL, &extra,
lr->key.allocated_at, print_record,
- /*allow_GDB_attach*/False );
+ /*allow_GDB_attach*/False, count_error );
}
void MC_(record_user_error) ( ThreadId tid, Addr a,
UInt n_this_record,
UInt n_total_records,
LossRecord* lossRecord,
- Bool print_record );
+ Bool print_record,
+ Bool count_error );
/* Is this address in a user-specified "ignored range" ? */
Bool MC_(in_ignored_range) ( Addr a );
// Print the loss records (in size order) and collect summary stats.
for (i = 0; i < n_lossrecords; i++) {
- Bool print_record;
+ Bool count_as_error, print_record;
// Rules for printing:
// - We don't show suppressed loss records ever (and that's controlled
// within the error manager).
// includes indirectly lost blocks!
//
lr = lr_array[i];
+ count_as_error = Unreached == lr->key.state ||
+ Possible == lr->key.state;
print_record = is_full_check &&
- ( MC_(clo_show_reachable) ||
- Unreached == lr->key.state ||
- Possible == lr->key.state );
+ ( MC_(clo_show_reachable) || count_as_error );
is_suppressed =
- MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr, print_record );
+ MC_(record_leak_error) ( tid, i+1, n_lossrecords, lr, print_record,
+ count_as_error );
if (is_suppressed) {
MC_(blocks_suppressed) += lr->num_blocks;
describe-block.stderr.exp describe-block.vgtest \
doublefree.stderr.exp doublefree.vgtest \
erringfds.stderr.exp erringfds.stdout.exp erringfds.vgtest \
- error_counts.stderr.exp error_counts.stdout.exp error_counts.vgtest \
+ error_counts.stderr.exp error_counts.vgtest \
errs1.stderr.exp errs1.vgtest \
exitprog.stderr.exp exitprog.vgtest \
execve.stderr.exp execve.vgtest \
assert(sizeof(long) == sizeof(void*));
/* Error counting */
- printf("errors: %d\n\n", VALGRIND_COUNT_ERRORS);
+ fprintf(stderr, "errors: %d\n\n", VALGRIND_COUNT_ERRORS);
if (x == 0) {
y++;
y--;
}
- printf("errors: %d\n\n", VALGRIND_COUNT_ERRORS);
+ fprintf(stderr, "errors: %d\n\n", VALGRIND_COUNT_ERRORS);
// Get a baseline, after start-up and also after printf (because Darwin
// printf allocates memory the first time it's called!)
GET_INITIAL_LEAK_COUNTS;
+ fprintf(stderr, "errors: %d\n\n", VALGRIND_COUNT_ERRORS);
+
/* Leak checking */
GET_FINAL_LEAK_COUNTS;
- PRINT_LEAK_COUNTS(stdout);
- printf("\n");
+ PRINT_LEAK_COUNTS(stderr);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, "errors: %d\n\n", VALGRIND_COUNT_ERRORS);
leaked = malloc(77);
leaked = 0;
reachable = malloc(99);
GET_FINAL_LEAK_COUNTS;
- PRINT_LEAK_COUNTS(stdout);
- printf("\n");
+ PRINT_LEAK_COUNTS(stderr);
+ fprintf(stderr, "\n");
- printf("errors: %d\n", VALGRIND_COUNT_ERRORS);
+ fprintf(stderr, "errors: %d\n", VALGRIND_COUNT_ERRORS);
return 0;
}
+errors: 0
+
+errors: 1
+
+errors: 1
+
+leaked: 0 bytes in 0 blocks
+dubious: 0 bytes in 0 blocks
+reachable: 0 bytes in 0 blocks
+suppressed: 0 bytes in 0 blocks
+
+errors: 1
+
+leaked: 77 bytes in 1 blocks
+dubious: 88 bytes in 1 blocks
+reachable: 99 bytes in 1 blocks
+suppressed: 0 bytes in 0 blocks
+
+errors: 3
+++ /dev/null
-errors: 0
-
-errors: 1
-
-leaked: 0 bytes in 0 blocks
-dubious: 0 bytes in 0 blocks
-reachable: 0 bytes in 0 blocks
-suppressed: 0 bytes in 0 blocks
-
-leaked: 77 bytes in 1 blocks
-dubious: 88 bytes in 1 blocks
-reachable: 99 bytes in 1 blocks
-suppressed: 0 bytes in 0 blocks
-
-errors: 10