Allows to only output "new" loss records when doing a leak search.

In the memcheck monitor 'leak_search', add a "new" keyword corresponding
to the delta leak search mode LCD_New.

Add a new client request VALGRIND_DO_NEW_LEAK_CHECK.

When doing a delta leak search, new loss records are marked with "new"
(whatever the delta leak search mode).

Note that trailing white spaces were removed in mc_main.c.
A much small diff can be looked at by using the -w diff option.
This commit is contained in:
Philippe Waroquiers 2022-12-30 20:05:40 +01:00
parent c8bb6a62ca
commit f6fcc74a68
15 changed files with 412 additions and 302 deletions

10
NEWS
View File

@ -15,6 +15,16 @@ AMD64/macOS 10.13 and nanoMIPS/Linux.
* ==================== TOOL CHANGES ===================
* Memcheck:
- When doing a delta leak_search, it is now possible to only
output the new loss records compared to the previous leak search.
This is available in the memcheck monitor command 'leak_search'
by specifying the "new" keyword or in your program by using
the client request VALGRIND_DO_NEW_LEAK_CHECK.
Whenever a "delta" leak search is done (i.e. when specifying
"new" or "increased" or "changed" in the monitor command),
the new loss records have a "new" marker.
* Helgrind:
- The option ---history-backtrace-size=<number> allows to configure
the number of entries to record in the stack traces of "old"

View File

@ -32,7 +32,7 @@ memcheck monitor commands:
leak_check [full*|summary|xtleak]
[kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]
[heuristics heur1,heur2,...]
[increased*|changed|any]
[new|increased*|changed|any]
[unlimited*|limited <max_loss_records_output>]
* = defaults
xtleak produces an xtree full leak result in xtleak.kcg.%p.%n
@ -106,7 +106,7 @@ memcheck monitor commands:
leak_check [full*|summary|xtleak]
[kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]
[heuristics heur1,heur2,...]
[increased*|changed|any]
[new|increased*|changed|any]
[unlimited*|limited <max_loss_records_output>]
* = defaults
xtleak produces an xtree full leak result in xtleak.kcg.%p.%n

View File

@ -2,8 +2,8 @@
expecting details 10 bytes reachable
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
expecting to have NO details
expecting details +10 bytes lost, +21 bytes reachable
expecting details +65 bytes reachable
@ -12,24 +12,30 @@ expecting details +10 bytes reachable
expecting details -10 bytes reachable, +10 bytes lost
expecting details -10 bytes lost, +10 bytes reachable
expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable
expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable
expecting to have NO details
finished
leaked: 32 bytes in 1 blocks
leaked: 117 bytes in 3 blocks
dubious: 0 bytes in 0 blocks
reachable: 64 bytes in 3 blocks
suppressed: 0 bytes in 0 blocks
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
21 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:23)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:24)
by 0x........: main (leak-delta.c:72)
32 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
33 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)

View File

@ -1,77 +1,89 @@
vgdb-error value changed from 0 to 999999
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
21 (+21) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:23)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:24)
by 0x........: main (leak-delta.c:72)
65 (+65) bytes in 2 (+2) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
0 (-10) bytes in 0 (-1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
0 (-10) bytes in 0 (-1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
32 (+32) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
33 (-32) bytes in 1 (-1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
42 (+42) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
43 (+43) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
21 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:23)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:24)
by 0x........: main (leak-delta.c:72)
32 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
33 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
32 bytes in 1 blocks are definitely lost in loss record ... of ...
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
33 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
33 bytes in 1 blocks are still reachable in loss record ... of ...
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
32 bytes in 1 blocks are definitely lost in loss record ... of ...
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)

View File

@ -70,6 +70,15 @@ continue
# fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme();
up
monitor leak_check full reachable changed
continue
# b42_43[0]--;
# fprintf(stderr, "expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable\n"); fflush(stderr); breakme();
up
monitor leak_check full reachable new
continue
# b42_43[1]--;
# fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
monitor leak_check full reachable new
# output all leak records:
monitor leak_check full reachable any unlimited
# output the 2 biggest leak records:

View File

@ -1,48 +1,56 @@
Breakpoint 1 at 0x........: file leak-delta.c, line 9.
Breakpoint 1 at 0x........: file leak-delta.c, line 10.
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:16
16 fprintf(stderr, "expecting details 10 bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:17
17 fprintf(stderr, "expecting details 10 bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:19
19 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:20
20 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:24
24 fprintf(stderr, "expecting details +10 bytes lost, +21 bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:25
25 fprintf(stderr, "expecting details +10 bytes lost, +21 bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:29
29 fprintf(stderr, "expecting details +65 bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:30
30 fprintf(stderr, "expecting details +65 bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:32
32 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:33
33 fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:36
36 fprintf(stderr, "expecting details +10 bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:37
37 fprintf(stderr, "expecting details +10 bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:40
40 fprintf(stderr, "expecting details -10 bytes reachable, +10 bytes lost\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:41
41 fprintf(stderr, "expecting details -10 bytes reachable, +10 bytes lost\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:44
44 fprintf(stderr, "expecting details -10 bytes lost, +10 bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:45
45 fprintf(stderr, "expecting details -10 bytes lost, +10 bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:9
9 static void breakme() {};
#1 0x........ in f () at leak-delta.c:48
48 fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme();
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:49
49 fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
#1 0x........ in f () at leak-delta.c:56
56 fprintf(stderr, "expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable\n"); fflush(stderr); breakme();
Continuing.
Breakpoint 1, breakme () at leak-delta.c:10
10 static void breakme() {};
Continuing.
Program exited normally.

View File

@ -1930,7 +1930,7 @@ Address 0x8049E28 len 1 defined
<para><varname>leak_check [full*|summary|xtleak]
[kinds &lt;set&gt;|reachable|possibleleak*|definiteleak]
[heuristics heur1,heur2,...]
[increased*|changed|any]
[new|increased*|changed|any]
[unlimited*|limited &lt;max_loss_records_output&gt;]
</varname>
performs a leak check. The <varname>*</varname> in the arguments
@ -1980,18 +1980,22 @@ Address 0x8049E28 len 1 defined
<varname>heuristics none</varname>.
</para>
<para>The <varname>[increased*|changed|any]</varname> argument controls what
kinds of changes are shown for a <varname>full</varname> leak search. The
value <varname>increased</varname> specifies that only block
<para>The <varname>[new|increased*|changed|any]</varname> argument controls
what kinds of changes are shown for a <varname>full</varname> leak search.
The value <varname>increased</varname> specifies that only block
allocation stacks with an increased number of leaked bytes or
blocks since the previous leak check should be shown. The
value <varname>changed</varname> specifies that allocation stacks
with any change since the previous leak check should be shown.
The value <varname>new</varname> specifies to show only the block
allocation stacks that are new since the previous leak search.
The value <varname>any</varname> specifies that all leak entries
should be shown, regardless of any increase or decrease. When
If <varname>increased</varname> or <varname>changed</varname> are
specified, the leak report entries will show the delta relative to
the previous leak report.
should be shown, regardless of any increase or decrease.
If <varname>new</varname> or <varname>increased</varname> or
<varname>changed</varname> are specified, the leak report entries will show
the delta relative to the previous leak report and the new loss records
will have a "new" marker (even when <varname>increased</varname> or
<varname>changed</varname> were specified).
</para>
<para>The following example shows usage of the
@ -2004,7 +2008,7 @@ Address 0x8049E28 len 1 defined
there was no increase since the previous leak search.</para>
<programlisting><![CDATA[
(gdb) monitor leak_check full possibleleak increased
==19520== 16 (+16) bytes in 1 (+1) blocks are possibly lost in loss record 9 of 12
==19520== 16 (+16) bytes in 1 (+1) blocks are possibly lost in new loss record 9 of 12
==19520== at 0x40070B4: malloc (vg_replace_malloc.c:263)
==19520== by 0x80484D5: mk (leak-cases.c:52)
==19520== by 0x804855F: f (leak-cases.c:81)
@ -2294,6 +2298,12 @@ arguments.</para>
has no return value.</para>
</listitem>
<listitem>
<para><varname>VALGRIND_DO_NEW_LEAK_CHECK</varname>: same as
<varname> VALGRIND_DO_LEAK_CHECK</varname> but only shows the new
entries since the previous leak search. It has no return value.</para>
</listitem>
<listitem>
<para><varname>VALGRIND_DO_QUICK_LEAK_CHECK</varname>: like
<varname>VALGRIND_DO_LEAK_CHECK</varname>, except it produces only a leak

View File

@ -329,9 +329,15 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
HChar d_direct_bytes[31];
HChar d_indirect_bytes[31];
HChar d_num_blocks[31];
/* A loss record that had an old number of blocks 0 is a new loss record.
We mark it as new only when doing any kind of delta leak search. */
const HChar *new_loss_record_marker
= MC_(detect_memory_leaks_last_delta_mode) != LCD_Any
&& lr->old_num_blocks == 0
? "new " : "";
MC_(snprintf_delta) (d_bytes, sizeof(d_bytes),
lr->szB + lr->indirect_szB,
lr->szB + lr->indirect_szB,
lr->old_szB + lr->old_indirect_szB,
MC_(detect_memory_leaks_last_delta_mode));
MC_(snprintf_delta) (d_direct_bytes, sizeof(d_direct_bytes),
@ -353,14 +359,15 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
emit( " <xwhat>\n" );
emit( " <text>%'lu%s (%'lu%s direct, %'lu%s indirect) bytes "
"in %'u%s blocks"
" are %s in loss record %'u of %'u</text>\n",
" are %s in %sloss record %'u of %'u</text>\n",
lr->szB + lr->indirect_szB, d_bytes,
lr->szB, d_direct_bytes,
lr->indirect_szB, d_indirect_bytes,
lr->num_blocks, d_num_blocks,
str_leak_lossmode(lr->key.state),
new_loss_record_marker,
n_this_record, n_total_records );
// Nb: don't put commas in these XML numbers
// Nb: don't put commas in these XML numbers
emit( " <leakedbytes>%lu</leakedbytes>\n",
lr->szB + lr->indirect_szB );
emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks );
@ -368,10 +375,11 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
} else {
emit( " <xwhat>\n" );
emit( " <text>%'lu%s bytes in %'u%s blocks"
" are %s in loss record %'u of %'u</text>\n",
" are %s in %sloss record %'u of %'u</text>\n",
lr->szB, d_direct_bytes,
lr->num_blocks, d_num_blocks,
str_leak_lossmode(lr->key.state),
str_leak_lossmode(lr->key.state),
new_loss_record_marker,
n_this_record, n_total_records );
emit( " <leakedbytes>%lu</leakedbytes>\n", lr->szB);
emit( " <leakedblocks>%u</leakedblocks>\n", lr->num_blocks);
@ -382,20 +390,22 @@ static void pp_LossRecord(UInt n_this_record, UInt n_total_records,
if (lr->indirect_szB > 0) {
emit(
"%'lu%s (%'lu%s direct, %'lu%s indirect) bytes in %'u%s blocks"
" are %s in loss record %'u of %'u\n",
" are %s in %sloss record %'u of %'u\n",
lr->szB + lr->indirect_szB, d_bytes,
lr->szB, d_direct_bytes,
lr->indirect_szB, d_indirect_bytes,
lr->num_blocks, d_num_blocks,
str_leak_lossmode(lr->key.state),
new_loss_record_marker,
n_this_record, n_total_records
);
} else {
emit(
"%'lu%s bytes in %'u%s blocks are %s in loss record %'u of %'u\n",
"%'lu%s bytes in %'u%s blocks are %s in %sloss record %'u of %'u\n",
lr->szB, d_direct_bytes,
lr->num_blocks, d_num_blocks,
str_leak_lossmode(lr->key.state),
new_loss_record_marker,
n_this_record, n_total_records
);
}

View File

@ -430,10 +430,11 @@ typedef
typedef
enum {
LCD_Any, // output all loss records, whatever the delta
LCD_Increased, // output loss records with an increase in size or blocks
LCD_Changed, // output loss records with an increase or
//decrease in size or blocks
LCD_Any, // Output all loss records, whatever the delta.
LCD_Increased, // Output loss records with an increase in size or blocks.
LCD_Changed, // Output loss records with an increase or
// decrease in size or blocks.
LCD_New // Output new loss records.
}
LeakCheckDeltaMode;

View File

@ -1275,25 +1275,29 @@ static void get_printing_rules(LeakCheckParams* lcp,
Bool delta_considered;
switch (lcp->deltamode) {
case LCD_Any:
case LCD_Any:
delta_considered = lr->num_blocks > 0;
break;
case LCD_Increased:
delta_considered
delta_considered
= lr->szB > lr->old_szB
|| lr->indirect_szB > lr->old_indirect_szB
|| lr->num_blocks > lr->old_num_blocks;
break;
case LCD_Changed:
case LCD_Changed:
delta_considered = lr->szB != lr->old_szB
|| lr->indirect_szB != lr->old_indirect_szB
|| lr->num_blocks != lr->old_num_blocks;
break;
case LCD_New:
delta_considered
= lr->num_blocks > 0 && lr->old_num_blocks == 0;
break;
default:
tl_assert(0);
}
*print_record = lcp->mode == LC_Full && delta_considered
*print_record = lcp->mode == LC_Full && delta_considered
&& RiS(lr->key.state,lcp->show_leak_kinds);
// We don't count a leaks as errors with lcp->mode==LC_Summary.
// Otherwise you can get high error counts with few or no error

View File

@ -10,7 +10,7 @@
This file is part of MemCheck, a heavyweight Valgrind tool for
detecting memory errors.
Copyright (C) 2000-2017 Julian Seward
Copyright (C) 2000-2017 Julian Seward
jseward@acm.org
This program is free software; you can redistribute it and/or
@ -64,7 +64,7 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */
/*------------------------------------------------------------*/
/*--- Fast-case knobs ---*/
/*------------------------------------------------------------*/
// Comment these out to disable the fast cases (don't just set them to zero).
/* PERF_FAST_LOADV is in mc_include.h */
@ -113,8 +113,8 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */
/*------------------------------------------------------------*/
/* All reads and writes are checked against a memory map (a.k.a. shadow
memory), which records the state of all memory in the process.
memory), which records the state of all memory in the process.
On 32-bit machines the memory map is organised as follows.
The top 16 bits of an address are used to index into a top-level
map table, containing 65536 entries. Each entry is a pointer to a
@ -222,7 +222,7 @@ static void ocache_sarp_Clear_Origins ( Addr, UWord ); /* fwds */
// Ie. instead of particular value bits being held in certain addresses, in
// this case certain addresses are represented by particular value bits.
// See insert_vabits2_into_vabits8() for an example.
//
//
// But note that we don't compress the V bits stored in registers; they
// need to be explicit to made the shadow operations possible. Therefore
// when moving values between registers and memory we need to convert
@ -272,7 +272,7 @@ static INLINE Bool is_start_of_sm ( Addr a ) {
STATIC_ASSERT(SM_CHUNKS % 2 == 0);
typedef
typedef
union {
UChar vabits8[SM_CHUNKS];
UShort vabits16[SM_CHUNKS/2];
@ -307,7 +307,7 @@ static SecMap* copy_for_writing ( SecMap* dist_sm )
new_sm = VG_(am_shadow_alloc)(sizeof(SecMap));
if (new_sm == NULL)
VG_(out_of_memory_NORETURN)( "memcheck:allocate new SecMap",
VG_(out_of_memory_NORETURN)( "memcheck:allocate new SecMap",
sizeof(SecMap) );
VG_(memcpy)(new_sm, dist_sm, sizeof(SecMap));
update_SM_counts(dist_sm, new_sm);
@ -358,14 +358,14 @@ static void update_SM_counts(SecMap* oldSM, SecMap* newSM)
if (n_noaccess_SMs > max_noaccess_SMs ) max_noaccess_SMs = n_noaccess_SMs;
if (n_undefined_SMs > max_undefined_SMs) max_undefined_SMs = n_undefined_SMs;
if (n_defined_SMs > max_defined_SMs ) max_defined_SMs = n_defined_SMs;
if (n_non_DSM_SMs > max_non_DSM_SMs ) max_non_DSM_SMs = n_non_DSM_SMs;
if (n_non_DSM_SMs > max_non_DSM_SMs ) max_non_DSM_SMs = n_non_DSM_SMs;
}
/* --------------- Primary maps --------------- */
/* The main primary map. This covers some initial part of the address
space, addresses 0 .. (N_PRIMARY_MAP << 16)-1. The rest of it is
handled using the auxiliary primary map.
handled using the auxiliary primary map.
*/
#if ENABLE_ASSEMBLY_HELPERS && defined(PERF_FAST_LOADV) \
&& (defined(VGP_arm_linux) \
@ -387,7 +387,7 @@ MC_MAIN_STATIC SecMap* primary_map[N_PRIMARY_MAP];
LAYOUT: the first word has to be the key for OSet fast lookups.
*/
typedef
struct {
struct {
Addr base;
SecMap* sm;
}
@ -403,7 +403,7 @@ typedef
static struct {
Addr base;
AuxMapEnt* ent; // pointer to the matching auxmap_L2 node
}
}
auxmap_L1[N_AUXMAP_L1];
static OSet* auxmap_L2 = NULL;
@ -451,7 +451,7 @@ static const HChar* check_auxmap_L1_L2_sanity ( Word* n_secmaps_found )
/* 32-bit platform */
if (VG_(OSetGen_Size)(auxmap_L2) != 0)
return "32-bit: auxmap_L2 is non-empty";
for (i = 0; i < N_AUXMAP_L1; i++)
for (i = 0; i < N_AUXMAP_L1; i++)
if (auxmap_L1[i].base != 0 || auxmap_L1[i].ent != NULL)
return "32-bit: auxmap_L1 is non-empty";
} else {
@ -631,8 +631,8 @@ static INLINE SecMap** get_secmap_high_ptr ( Addr a )
static INLINE SecMap** get_secmap_ptr ( Addr a )
{
return ( a <= MAX_PRIMARY_ADDRESS
? get_secmap_low_ptr(a)
return ( a <= MAX_PRIMARY_ADDRESS
? get_secmap_low_ptr(a)
: get_secmap_high_ptr(a));
}
@ -665,7 +665,7 @@ static INLINE SecMap* get_secmap_for_writing_high ( Addr a )
/* Produce the secmap for 'a', either from the primary map or by
ensuring there is an entry for it in the aux primary map. The
secmap may be a distinguished one as the caller will only want to
be able to read it.
be able to read it.
*/
static INLINE SecMap* get_secmap_for_reading ( Addr a )
{
@ -767,7 +767,7 @@ UChar get_vabits2 ( Addr a )
// *** WARNING! ***
// Any time this function is called, if it is possible that any of the
// 4 2-bit fields in vabits8 are equal to VA_BITS2_PARTDEFINED, then the
// 4 2-bit fields in vabits8 are equal to VA_BITS2_PARTDEFINED, then the
// corresponding entry(s) in the sec-V-bits table must also be set!
static INLINE
UChar get_vabits8_for_aligned_word32 ( Addr a )
@ -847,13 +847,13 @@ Bool get_vbits8 ( Addr a, UChar* vbits8 )
// Note: the nodes in this table can become stale. Eg. if you write a PDB,
// then overwrite the same address with a fully defined byte, the sec-V-bit
// node will not necessarily be removed. This is because checking for
// whether removal is necessary would slow down the fast paths.
// whether removal is necessary would slow down the fast paths.
//
// To avoid the stale nodes building up too much, we periodically (once the
// table reaches a certain size) garbage collect (GC) the table by
// traversing it and evicting any nodes not having PDB.
// If more than a certain proportion of nodes survived, we increase the
// table size so that GCs occur less often.
// table size so that GCs occur less often.
//
// This policy is designed to avoid bad table bloat in the worst case where
// a program creates huge numbers of stale PDBs -- we would get this bloat
@ -881,7 +881,7 @@ Bool get_vbits8 ( Addr a, UChar* vbits8 )
// will be deleted and re-added less frequently.
//
// The previous scaling up mechanism (now called STEPUP) is retained:
// if residency exceeds 50%, the table is scaled up, although by a
// if residency exceeds 50%, the table is scaled up, although by a
// factor sqrt(2) rather than 2 as before. This effectively doubles the
// frequency of GCs when there are many PDBs at reduces the tendency of
// stale PDBs to reside for long periods in the table.
@ -930,20 +930,20 @@ static Int secVBitLimit = 1000;
// come out anyway.
static UInt GCs_done = 0;
typedef
typedef
struct {
Addr a;
UChar vbits8[BYTES_PER_SEC_VBIT_NODE];
}
}
SecVBitNode;
static OSet* createSecVBitTable(void)
{
OSet* newSecVBitTable;
newSecVBitTable = VG_(OSetGen_Create_With_Pool)
( offsetof(SecVBitNode, a),
( offsetof(SecVBitNode, a),
NULL, // use fast comparisons
VG_(malloc), "mc.cSVT.1 (sec VBit table)",
VG_(malloc), "mc.cSVT.1 (sec VBit table)",
VG_(free),
1000,
sizeof(SecVBitNode));
@ -971,7 +971,7 @@ static void gcSecVBitTable(void)
if (VA_BITS2_PARTDEFINED == get_vabits2(n->a + i)) {
// Found a non-stale byte, so keep =>
// Insert a copy of the node into the new table.
SecVBitNode* n2 =
SecVBitNode* n2 =
VG_(OSetGen_AllocNode)(secVBitTable2, sizeof(SecVBitNode));
*n2 = *n;
VG_(OSetGen_Insert)(secVBitTable2, n2);
@ -994,7 +994,7 @@ static void gcSecVBitTable(void)
}
// Increase table size if necessary.
if ((Double)n_survivors
if ((Double)n_survivors
> ((Double)secVBitLimit * STEPUP_SURVIVOR_PROPORTION)) {
secVBitLimit = (Int)((Double)secVBitLimit * (Double)STEPUP_GROWTH_FACTOR);
if (VG_(clo_verbosity) > 1)
@ -1004,7 +1004,7 @@ static void gcSecVBitTable(void)
}
else
if (secVBitLimit < DRIFTUP_MAX_SIZE
&& (Double)n_survivors
&& (Double)n_survivors
> ((Double)secVBitLimit * DRIFTUP_SURVIVOR_PROPORTION)) {
secVBitLimit = (Int)((Double)secVBitLimit * (Double)DRIFTUP_GROWTH_FACTOR);
if (VG_(clo_verbosity) > 1)
@ -1069,7 +1069,7 @@ static void set_sec_vbits8(Addr a, UWord vbits8)
/* Returns the offset in memory of the byteno-th most significant byte
in a wordszB-sized word, given the specified endianness. */
static INLINE UWord byte_offset_w ( UWord wordszB, Bool bigendian,
static INLINE UWord byte_offset_w ( UWord wordszB, Bool bigendian,
UWord byteno ) {
return bigendian ? (wordszB-1-byteno) : byteno;
}
@ -1460,7 +1460,7 @@ ULong mc_LOADVn_slow ( Addr a, SizeT nBits, Bool bigendian )
PROF_EVENT(MCPE_LOADVN_SLOW_LOOP);
ai = a + byte_offset_w(szB, bigendian, i);
ok = get_vbits8(ai, &vbits8);
vbits64 <<= 8;
vbits64 <<= 8;
vbits64 |= vbits8;
if (!ok) n_addrs_bad++;
pessim64 <<= 8;
@ -1590,7 +1590,7 @@ void mc_STOREVn_slow ( Addr a, SizeT nBits, ULong vbytes, Bool bigendian )
SecMap* sm = get_secmap_for_reading(a);
UWord sm_off16 = SM_OFF_16(a);
UWord vabits16 = sm->vabits16[sm_off16];
if (LIKELY( !is_distinguished_sm(sm) &&
if (LIKELY( !is_distinguished_sm(sm) &&
(VA_BITS16_DEFINED == vabits16 ||
VA_BITS16_UNDEFINED == vabits16) )) {
/* Handle common case quickly: a is suitably aligned, */
@ -1617,7 +1617,7 @@ void mc_STOREVn_slow ( Addr a, SizeT nBits, ULong vbytes, Bool bigendian )
SecMap* sm = get_secmap_for_reading(a);
UWord sm_off = SM_OFF(a);
UWord vabits8 = sm->vabits8[sm_off];
if (LIKELY( !is_distinguished_sm(sm) &&
if (LIKELY( !is_distinguished_sm(sm) &&
(VA_BITS8_DEFINED == vabits8 ||
VA_BITS8_UNDEFINED == vabits8) )) {
/* Handle common case quickly: a is suitably aligned, */
@ -1727,7 +1727,7 @@ static void set_address_range_perms ( Addr a, SizeT lenT, UWord vabits16,
// * one partial sec-map (p) 1
// - one whole sec-map (P) 2
//
// * two partial sec-maps (pp) 1,3
// * two partial sec-maps (pp) 1,3
// - one partial, one whole sec-map (pP) 1,2
// - one whole, one partial sec-map (Pp) 2,3
// - two whole sec-maps (PP) 2,2
@ -1976,7 +1976,7 @@ static void make_mem_defined_if_addressable ( Addr a, SizeT len )
set_vabits2(a+i, VA_BITS2_DEFINED);
if (UNLIKELY(MC_(clo_mc_level) >= 3)) {
MC_(helperc_b_store1)( a+i, 0 ); /* clear the origin tag */
}
}
}
}
}
@ -1993,7 +1993,7 @@ static void make_mem_defined_if_noaccess ( Addr a, SizeT len )
set_vabits2(a+i, VA_BITS2_DEFINED);
if (UNLIKELY(MC_(clo_mc_level) >= 3)) {
MC_(helperc_b_store1)( a+i, 0 ); /* clear the origin tag */
}
}
}
}
}
@ -2024,8 +2024,8 @@ void MC_(copy_address_range_state) ( Addr src, Addr dst, SizeT len )
while (len >= 4) {
vabits8 = get_vabits8_for_aligned_word32( src+i );
set_vabits8_for_aligned_word32( dst+i, vabits8 );
if (LIKELY(VA_BITS8_DEFINED == vabits8
|| VA_BITS8_UNDEFINED == vabits8
if (LIKELY(VA_BITS8_DEFINED == vabits8
|| VA_BITS8_UNDEFINED == vabits8
|| VA_BITS8_NOACCESS == vabits8)) {
/* do nothing */
} else {
@ -2541,7 +2541,7 @@ static void init_OCache ( void )
tl_assert(ocacheL1 == NULL);
ocacheL1 = VG_(am_shadow_alloc)(sizeof(OCache));
if (ocacheL1 == NULL) {
VG_(out_of_memory_NORETURN)( "memcheck:allocating ocacheL1",
VG_(out_of_memory_NORETURN)( "memcheck:allocating ocacheL1",
sizeof(OCache) );
}
tl_assert(ocacheL1 != NULL);
@ -2708,7 +2708,7 @@ static OCacheLine* find_OCacheLine_SLOW ( Addr a )
} else {
stats_ocacheL1_found_at_N++;
}
if (UNLIKELY(0 == (ocacheL1_event_ctr++
if (UNLIKELY(0 == (ocacheL1_event_ctr++
& ((1<<OC_MOVE_FORWARDS_EVERY_BITS)-1)))) {
moveLineForwards( &ocacheL1->set[setno], line );
line--;
@ -2802,7 +2802,7 @@ static INLINE void set_aligned_word64_Origin_to_undef ( Addr a, UInt otag )
{ OCacheLine* line;
UWord lineoff = oc_line_offset(a);
if (OC_ENABLE_ASSERTIONS) {
tl_assert(lineoff >= 0
tl_assert(lineoff >= 0
&& lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/);
}
line = find_OCacheLine( a );
@ -2940,7 +2940,7 @@ void make_aligned_word64_undefined_w_otag ( Addr a, UInt otag )
//// Set the origins for a+0 .. a+7
{ OCacheLine* line;
UWord lineoff = oc_line_offset(a);
tl_assert(lineoff >= 0
tl_assert(lineoff >= 0
&& lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/);
line = find_OCacheLine( a );
line->u.main.descr[lineoff+0] = 0xF;
@ -2978,7 +2978,7 @@ void make_aligned_word64_noaccess ( Addr a )
if (UNLIKELY( MC_(clo_mc_level) == 3 )) {
OCacheLine* line;
UWord lineoff = oc_line_offset(a);
tl_assert(lineoff >= 0
tl_assert(lineoff >= 0
&& lineoff < OC_W32S_PER_LINE -1/*'cos 8-aligned*/);
line = find_OCacheLine( a );
line->u.main.descr[lineoff+0] = 0;
@ -3777,7 +3777,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_w_o) ( Addr base, UWord len, Addr nia )
} else {
MC_(make_mem_undefined_w_otag)(base, len, otag);
}
# endif
# endif
/* Idea is: go fast when
* 8-aligned and length is 128
@ -3974,7 +3974,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_no_o) ( Addr base, UWord len )
} else {
make_mem_undefined(base, len);
}
# endif
# endif
/* Idea is: go fast when
* 8-aligned and length is 128
@ -4118,7 +4118,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base )
} else {
make_mem_undefined(base, 128);
}
# endif
# endif
/* Idea is: go fast when
* 16-aligned and length is 128
@ -4162,7 +4162,7 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base )
}
}
}
/* The same, but for when base is 8 % 16, which is the situation
with RSP for amd64-ELF immediately after call instructions.
*/
@ -4214,12 +4214,12 @@ void MC_(helperc_MAKE_STACK_UNINIT_128_no_o) ( Addr base )
/*--- Checking memory ---*/
/*------------------------------------------------------------*/
typedef
typedef
enum {
MC_Ok = 5,
MC_AddrErr = 6,
MC_Ok = 5,
MC_AddrErr = 6,
MC_ValueErr = 7
}
}
MC_ReadResult;
@ -4249,7 +4249,7 @@ Bool MC_(check_mem_is_noaccess) ( Addr a, SizeT len, Addr* bad_addr )
return True;
}
static Bool is_mem_addressable ( Addr a, SizeT len,
static Bool is_mem_addressable ( Addr a, SizeT len,
/*OUT*/Addr* bad_addr )
{
SizeT i;
@ -4337,8 +4337,8 @@ static void is_mem_defined_comprehensive (
PROF_EVENT(MCPE_IS_MEM_DEFINED_COMPREHENSIVE_LOOP);
vabits2 = get_vabits2(a);
switch (vabits2) {
case VA_BITS2_DEFINED:
a++;
case VA_BITS2_DEFINED:
a++;
break;
case VA_BITS2_UNDEFINED:
case VA_BITS2_PARTDEFINED:
@ -4421,7 +4421,7 @@ void check_mem_is_addressable ( CorePart part, ThreadId tid, const HChar* s,
if (!ok) {
switch (part) {
case Vg_CoreSysCall:
MC_(record_memparam_error) ( tid, bad_addr,
MC_(record_memparam_error) ( tid, bad_addr,
/*isAddrErr*/True, s, 0/*otag*/ );
break;
@ -4438,7 +4438,7 @@ void check_mem_is_addressable ( CorePart part, ThreadId tid, const HChar* s,
static
void check_mem_is_defined ( CorePart part, ThreadId tid, const HChar* s,
Addr base, SizeT size )
{
{
UInt otag = 0;
Addr bad_addr;
MC_ReadResult res = is_mem_defined ( base, size, &bad_addr, &otag );
@ -4451,12 +4451,12 @@ void check_mem_is_defined ( CorePart part, ThreadId tid, const HChar* s,
MC_(record_memparam_error) ( tid, bad_addr, isAddrErr, s,
isAddrErr ? 0 : otag );
break;
case Vg_CoreSysCallArgInMem:
MC_(record_regparam_error) ( tid, s, otag );
break;
/* If we're being asked to jump to a silly address, record an error
/* If we're being asked to jump to a silly address, record an error
message before potentially crashing the entire system. */
case Vg_CoreTranslate:
MC_(record_jump_error)( tid, bad_addr );
@ -4571,7 +4571,7 @@ void mc_new_mem_startup( Addr a, SizeT len,
{
// Because code is defined, initialised variables get put in the data
// segment and are defined, and uninitialised variables get put in the
// bss segment and are auto-zeroed (and so defined).
// bss segment and are auto-zeroed (and so defined).
//
// It's possible that there will be padding between global variables.
// This will also be auto-zeroed, and marked as defined by Memcheck. If
@ -4629,7 +4629,7 @@ static UInt mb_get_origin_for_guest_offset ( ThreadId tid,
chunks of guest state, hence the _SIZE value, which has to be as
big as the biggest guest state.
*/
static void mc_post_reg_write ( CorePart part, ThreadId tid,
static void mc_post_reg_write ( CorePart part, ThreadId tid,
PtrdiffT offset, SizeT size)
{
# define MAX_REG_WRITE_SIZE 2264
@ -4640,18 +4640,18 @@ static void mc_post_reg_write ( CorePart part, ThreadId tid,
# undef MAX_REG_WRITE_SIZE
}
static
void mc_post_reg_write_clientcall ( ThreadId tid,
static
void mc_post_reg_write_clientcall ( ThreadId tid,
PtrdiffT offset, SizeT size, Addr f)
{
mc_post_reg_write(/*dummy*/0, tid, offset, size);
}
/* Look at the definedness of the guest's shadow state for
[offset, offset+len). If any part of that is undefined, record
/* Look at the definedness of the guest's shadow state for
[offset, offset+len). If any part of that is undefined, record
a parameter error.
*/
static void mc_pre_reg_read ( CorePart part, ThreadId tid, const HChar* s,
static void mc_pre_reg_read ( CorePart part, ThreadId tid, const HChar* s,
PtrdiffT offset, SizeT size)
{
Int i;
@ -5088,7 +5088,7 @@ void mc_STOREV64 ( Addr a, ULong vbits64, Bool isBigEndian )
if (!is_distinguished_sm(sm) && VA_BITS16_DEFINED == vabits16) {
sm->vabits16[sm_off16] = VA_BITS16_UNDEFINED;
return;
}
}
PROF_EVENT(MCPE_STOREV64_SLOW3);
mc_STOREVn_slow( a, 64, vbits64, isBigEndian );
return;
@ -5303,7 +5303,7 @@ __asm__( /* Derived from NCode template */
".global vgMemCheck_helperc_LOADV16le \n"
".type vgMemCheck_helperc_LOADV16le, %function \n"
"vgMemCheck_helperc_LOADV16le: \n" //
" tst r0, #1 \n" //
" tst r0, #1 \n" //
" bne .LLV16LEc12 \n" // if misaligned
" lsr r2, r0, #16 \n" // r2 = pri-map-ix
" movw r3, #:lower16:primary_map \n" //
@ -5445,7 +5445,7 @@ void mc_STOREV16 ( Addr a, UWord vbits16, Bool isBigEndian )
if (LIKELY(vabits8 == VA_BITS8_DEFINED)) {
return;
}
if (!is_distinguished_sm(sm)
if (!is_distinguished_sm(sm)
&& accessible_vabits4_in_vabits8(a, vabits8)) {
insert_vabits4_into_vabits8( a, VA_BITS4_DEFINED,
&(sm->vabits8[sm_off]) );
@ -5458,7 +5458,7 @@ void mc_STOREV16 ( Addr a, UWord vbits16, Bool isBigEndian )
if (vabits8 == VA_BITS8_UNDEFINED) {
return;
}
if (!is_distinguished_sm(sm)
if (!is_distinguished_sm(sm)
&& accessible_vabits4_in_vabits8(a, vabits8)) {
insert_vabits4_into_vabits8( a, VA_BITS4_UNDEFINED,
&(sm->vabits8[sm_off]) );
@ -5693,7 +5693,7 @@ void MC_(helperc_STOREV8) ( Addr a, UWord vbits8 )
if (LIKELY(vabits8 == VA_BITS8_DEFINED)) {
return; // defined on defined
}
if (!is_distinguished_sm(sm)
if (!is_distinguished_sm(sm)
&& VA_BITS2_NOACCESS != extract_vabits2_from_vabits8(a, vabits8)) {
// direct mod
insert_vabits2_into_vabits8( a, VA_BITS2_DEFINED,
@ -5708,8 +5708,8 @@ void MC_(helperc_STOREV8) ( Addr a, UWord vbits8 )
if (vabits8 == VA_BITS8_UNDEFINED) {
return; // undefined on undefined
}
if (!is_distinguished_sm(sm)
&& (VA_BITS2_NOACCESS
if (!is_distinguished_sm(sm)
&& (VA_BITS2_NOACCESS
!= extract_vabits2_from_vabits8(a, vabits8))) {
// direct mod
insert_vabits2_into_vabits8( a, VA_BITS2_UNDEFINED,
@ -5755,7 +5755,7 @@ void MC_(helperc_value_check8_fail_w_o) ( UWord origin ) {
MC_(record_value_error) ( VG_(get_running_tid)(), 8, (UInt)origin );
}
VG_REGPARM(2)
VG_REGPARM(2)
void MC_(helperc_value_checkN_fail_w_o) ( HWord sz, UWord origin ) {
MC_(record_value_error) ( VG_(get_running_tid)(), (Int)sz, (UInt)origin );
}
@ -5782,7 +5782,7 @@ void MC_(helperc_value_check8_fail_no_o) ( void ) {
MC_(record_value_error) ( VG_(get_running_tid)(), 8, 0/*origin*/ );
}
VG_REGPARM(1)
VG_REGPARM(1)
void MC_(helperc_value_checkN_fail_no_o) ( HWord sz ) {
MC_(record_value_error) ( VG_(get_running_tid)(), (Int)sz, 0/*origin*/ );
}
@ -5801,13 +5801,13 @@ void MC_(helperc_value_checkN_fail_no_o) ( HWord sz ) {
/* Nb: We used to issue various definedness/addressability errors from here,
but we took them out because they ranged from not-very-helpful to
downright annoying, and they complicated the error data structures. */
static Int mc_get_or_set_vbits_for_client (
Addr a,
Addr vbits,
SizeT szB,
Bool setting, /* True <=> set vbits, False <=> get vbits */
Bool is_client_request /* True <=> real user request
False <=> internal call from gdbserver */
static Int mc_get_or_set_vbits_for_client (
Addr a,
Addr vbits,
SizeT szB,
Bool setting, /* True <=> set vbits, False <=> get vbits */
Bool is_client_request /* True <=> real user request
False <=> internal call from gdbserver */
)
{
SizeT i;
@ -5918,7 +5918,7 @@ static void init_shadow_memory ( void )
/* Auxiliary primary maps */
init_auxmap_L1_L2();
/* auxmap_size = auxmap_used = 0;
/* auxmap_size = auxmap_used = 0;
no ... these are statically initialised */
/* Secondary V bit table */
@ -6320,7 +6320,7 @@ static void mc_print_usage(void)
}
static void mc_print_debug_usage(void)
{
{
VG_(printf)(
" (none)\n"
);
@ -6332,13 +6332,13 @@ static void mc_print_debug_usage(void)
/*------------------------------------------------------------*/
/* Client block management:
This is managed as an expanding array of client block descriptors.
Indices of live descriptors are issued to the client, so it can ask
to free them later. Therefore we cannot slide live entries down
over dead ones. Instead we must use free/inuse flags and scan for
an empty slot at allocation time. This in turn means allocation is
relatively expensive, so we hope this does not happen too often.
relatively expensive, so we hope this does not happen too often.
An unused block has start == size == 0
*/
@ -6391,7 +6391,7 @@ Int alloc_client_block ( void )
sz_new = (cgbs == NULL) ? 10 : (2 * cgb_size);
cgbs_new = VG_(malloc)( "mc.acb.1", sz_new * sizeof(CGenBlock) );
for (i = 0; i < cgb_used; i++)
for (i = 0; i < cgb_used; i++)
cgbs_new[i] = cgbs[i];
if (cgbs != NULL)
@ -6408,14 +6408,14 @@ Int alloc_client_block ( void )
static void show_client_block_stats ( void )
{
VG_(message)(Vg_DebugMsg,
VG_(message)(Vg_DebugMsg,
"general CBs: %llu allocs, %llu discards, %llu maxinuse, %llu search\n",
cgb_allocs, cgb_discards, cgb_used_MAX, cgb_search
cgb_allocs, cgb_discards, cgb_used_MAX, cgb_search
);
}
static void print_monitor_help ( void )
{
VG_(gdb_printf)
VG_(gdb_printf)
(
"\n"
"memcheck monitor commands:\n"
@ -6436,7 +6436,7 @@ static void print_monitor_help ( void )
" leak_check [full*|summary|xtleak]\n"
" [kinds kind1,kind2,...|reachable|possibleleak*|definiteleak]\n"
" [heuristics heur1,heur2,...]\n"
" [increased*|changed|any]\n"
" [new|increased*|changed|any]\n"
" [unlimited*|limited <max_loss_records_output>]\n"
" * = defaults\n"
" xtleak produces an xtree full leak result in xtleak.kcg.%%p.%%n\n"
@ -6574,9 +6574,9 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
/* NB: if possible, avoid introducing a new command below which
starts with the same first letter(s) as an already existing
command. This ensures a shorter abbreviation for the user. */
switch (VG_(keyword_id)
switch (VG_(keyword_id)
("help get_vbits leak_check make_memory check_memory "
"block_list who_points_at xb xtmemory",
"block_list who_points_at xb xtmemory",
wcmd, kwd_report_duplicated_matches)) {
case -2: /* multiple matches */
return True;
@ -6593,10 +6593,10 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
Int i;
Int unaddressable = 0;
for (i = 0; i < szB; i++) {
Int res = mc_get_or_set_vbits_for_client
(address+i, (Addr) &vbits, 1,
Int res = mc_get_or_set_vbits_for_client
(address+i, (Addr) &vbits, 1,
False, /* get them */
False /* is client request */ );
False /* is client request */ );
/* we are before the first character on next line, print a \n. */
if ((i % 32) == 0 && i != 0)
VG_(printf) ("\n");
@ -6625,7 +6625,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
LeakCheckParams lcp;
HChar* xt_filename = NULL;
HChar* kw;
lcp.mode = LC_Full;
lcp.show_leak_kinds = R2S(Possible) | R2S(Unreached);
lcp.errors_for_leak_kinds = 0; // no errors for interactive leak search.
@ -6634,15 +6634,15 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
lcp.max_loss_records_output = 999999999;
lcp.requested_by_monitor_command = True;
lcp.xt_filename = NULL;
for (kw = VG_(strtok_r) (NULL, " ", &ssaveptr);
kw != NULL;
for (kw = VG_(strtok_r) (NULL, " ", &ssaveptr);
kw != NULL;
kw = VG_(strtok_r) (NULL, " ", &ssaveptr)) {
switch (VG_(keyword_id)
switch (VG_(keyword_id)
("full summary xtleak "
"kinds reachable possibleleak definiteleak "
"heuristics "
"increased changed any "
"new increased changed any "
"unlimited limited ",
kw, kwd_report_all)) {
case -2: err++; break;
@ -6653,14 +6653,14 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
lcp.mode = LC_Summary; break;
case 2: /* xtleak */
lcp.mode = LC_Full;
xt_filename
xt_filename
= VG_(expand_file_name)("--xtleak-mc_main.c",
"xtleak.kcg.%p.%n");
lcp.xt_filename = xt_filename;
break;
case 3: { /* kinds */
wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
if (wcmd == NULL
if (wcmd == NULL
|| !VG_(parse_enum_set)(MC_(parse_leak_kinds_tokens),
True/*allow_all*/,
wcmd,
@ -6674,7 +6674,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
lcp.show_leak_kinds = MC_(all_Reachedness)();
break;
case 5: /* possibleleak */
lcp.show_leak_kinds
lcp.show_leak_kinds
= R2S(Possible) | R2S(IndirectLeak) | R2S(Unreached);
break;
case 6: /* definiteleak */
@ -6682,7 +6682,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
break;
case 7: { /* heuristics */
wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
if (wcmd == NULL
if (wcmd == NULL
|| !VG_(parse_enum_set)(MC_(parse_leak_heuristics_tokens),
True,/*allow_all*/
wcmd,
@ -6692,15 +6692,17 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
}
break;
}
case 8: /* increased */
case 8: /* new */
lcp.deltamode = LCD_New; break;
case 9: /* increased */
lcp.deltamode = LCD_Increased; break;
case 9: /* changed */
case 10: /* changed */
lcp.deltamode = LCD_Changed; break;
case 10: /* any */
case 11: /* any */
lcp.deltamode = LCD_Any; break;
case 11: /* unlimited */
case 12: /* unlimited */
lcp.max_loss_records_output = 999999999; break;
case 12: { /* limited */
case 13: { /* limited */
Int int_value;
const HChar* endptr;
@ -6732,11 +6734,11 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
VG_(free)(xt_filename);
return True;
}
case 3: { /* make_memory */
Addr address;
SizeT szB = 1;
Int kwdid = VG_(keyword_id)
Int kwdid = VG_(keyword_id)
("noaccess undefined defined Definedifaddressable",
VG_(strtok_r) (NULL, " ", &ssaveptr), kwd_report_all);
if (!VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr))
@ -6745,7 +6747,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
case -2: break;
case -1: break;
case 0: MC_(make_mem_noaccess) (address, szB); break;
case 1: make_mem_undefined_w_tid_and_okind ( address, szB, tid,
case 1: make_mem_undefined_w_tid_and_okind ( address, szB, tid,
MC_OKIND_USER ); break;
case 2: MC_(make_mem_defined) ( address, szB ); break;
case 3: make_mem_defined_if_addressable ( address, szB ); break;;
@ -6765,7 +6767,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
ExeContext* origin_ec;
MC_ReadResult res;
Int kwdid = VG_(keyword_id)
Int kwdid = VG_(keyword_id)
("addressable defined",
VG_(strtok_r) (NULL, " ", &ssaveptr), kwd_report_all);
if (!VG_(strtok_get_address_and_size) (&address, &szB, &ssaveptr))
@ -6775,7 +6777,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
case -1: break;
case 0: /* addressable */
if (is_mem_addressable ( address, szB, &bad_addr ))
VG_(printf) ("Address %p len %lu addressable\n",
VG_(printf) ("Address %p len %lu addressable\n",
(void *)address, szB);
else
VG_(printf)
@ -6793,17 +6795,17 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
else if (MC_ValueErr == res) {
okind = otag & 3;
switch (okind) {
case MC_OKIND_STACK:
case MC_OKIND_STACK:
src = " was created by a stack allocation"; break;
case MC_OKIND_HEAP:
case MC_OKIND_HEAP:
src = " was created by a heap allocation"; break;
case MC_OKIND_USER:
case MC_OKIND_USER:
src = " was created by a client request"; break;
case MC_OKIND_UNKNOWN:
case MC_OKIND_UNKNOWN:
src = ""; break;
default: tl_assert(0);
}
VG_(printf)
VG_(printf)
("Address %p len %lu not defined:\n"
"Uninitialised value at %p%s\n",
(void *)address, szB, (void *) bad_addr, src);
@ -6834,11 +6836,11 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
UInt limit_blocks = 999999999;
Int int_value;
UInt heuristics = 0;
for (wl = VG_(strtok_r) (NULL, " ", &ssaveptr);
wl != NULL;
wl = VG_(strtok_r) (NULL, " ", &ssaveptr)) {
switch (VG_(keyword_id) ("unlimited limited heuristics ",
switch (VG_(keyword_id) ("unlimited limited heuristics ",
wl, kwd_report_all)) {
case -2: return True;
case -1: return True;
@ -6864,7 +6866,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
break;
case 2: /* heuristics */
wcmd = VG_(strtok_r) (NULL, " ", &ssaveptr);
if (wcmd == NULL
if (wcmd == NULL
|| !VG_(parse_enum_set)(MC_(parse_leak_heuristics_tokens),
True,/*allow_all*/
wcmd,
@ -6955,7 +6957,7 @@ static Bool handle_gdb_monitor_command (ThreadId tid, HChar *req)
return True;
}
default:
default:
tl_assert(0);
return False;
}
@ -7002,7 +7004,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
UInt otagV = 0;
Bool errorA = False;
Addr bad_addrA = 0;
is_mem_defined_comprehensive(
is_mem_defined_comprehensive(
arg[1], arg[2],
&errorV, &bad_addrV, &otagV, &errorA, &bad_addrA
);
@ -7030,17 +7032,17 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
case VG_USERREQ__DO_LEAK_CHECK: {
LeakCheckParams lcp;
if (arg[1] == 0)
lcp.mode = LC_Full;
else if (arg[1] == 1)
lcp.mode = LC_Summary;
else {
VG_(message)(Vg_UserMsg,
VG_(message)(Vg_UserMsg,
"Warning: unknown memcheck leak search mode\n");
lcp.mode = LC_Full;
}
lcp.show_leak_kinds = MC_(clo_show_leak_kinds);
lcp.errors_for_leak_kinds = MC_(clo_error_for_leak_kinds);
lcp.heuristics = MC_(clo_leak_check_heuristics);
@ -7051,16 +7053,18 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
lcp.deltamode = LCD_Increased;
else if (arg[2] == 2)
lcp.deltamode = LCD_Changed;
else if (arg[2] == 3)
lcp.deltamode = LCD_New;
else {
VG_(message)
(Vg_UserMsg,
(Vg_UserMsg,
"Warning: unknown memcheck leak search deltamode\n");
lcp.deltamode = LCD_Any;
}
lcp.max_loss_records_output = 999999999;
lcp.requested_by_monitor_command = False;
lcp.xt_filename = NULL;
MC_(detect_memory_leaks)(tid, &lcp);
*ret = 0; /* return value is meaningless */
break;
@ -7072,7 +7076,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
break;
case VG_USERREQ__MAKE_MEM_UNDEFINED:
make_mem_undefined_w_tid_and_okind ( arg[1], arg[2], tid,
make_mem_undefined_w_tid_and_okind ( arg[1], arg[2], tid,
MC_OKIND_USER );
*ret = -1;
break;
@ -7101,7 +7105,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
break;
case VG_USERREQ__DISCARD: /* discard */
if (cgbs == NULL
if (cgbs == NULL
|| arg[2] >= cgb_used ||
(cgbs[arg[2]].start == 0 && cgbs[arg[2]].size == 0)) {
*ret = 1;
@ -7117,7 +7121,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
case VG_USERREQ__GET_VBITS:
*ret = mc_get_or_set_vbits_for_client
( arg[1], arg[2], arg[3],
False /* get them */,
False /* get them */,
True /* is client request */ );
break;
@ -7164,7 +7168,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
UInt rzB = arg[3];
Bool is_zeroed = (Bool)arg[4];
MC_(new_block) ( tid, p, sizeB, /*ignored*/0, is_zeroed,
MC_(new_block) ( tid, p, sizeB, /*ignored*/0, is_zeroed,
MC_AllocCustom, MC_(malloc_list) );
if (rzB > 0) {
MC_(make_mem_noaccess) ( p - rzB, rzB);
@ -7206,7 +7210,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
// The create_mempool function does not know these mempool flags,
// pass as booleans.
MC_(create_mempool) ( pool, rzB, is_zeroed,
MC_(create_mempool) ( pool, rzB, is_zeroed,
(flags & VALGRIND_MEMPOOL_AUTO_FREE),
(flags & VALGRIND_MEMPOOL_METAPOOL) );
return True;
@ -7291,7 +7295,7 @@ static Bool mc_handle_client_request ( ThreadId tid, UWord* arg, UWord* ret )
default:
VG_(message)(
Vg_UserMsg,
Vg_UserMsg,
"Warning: unknown memcheck client request code %llx\n",
(ULong)arg[0]
);
@ -7320,10 +7324,10 @@ static const HChar* MC_(event_ctr_name)[MCPE_LAST] = {
[MCPE_STOREVN_SLOW] = "STOREVn_slow",
[MCPE_STOREVN_SLOW_LOOP] = "STOREVn_slow(loop)",
[MCPE_MAKE_ALIGNED_WORD32_UNDEFINED] = "make_aligned_word32_undefined",
[MCPE_MAKE_ALIGNED_WORD32_UNDEFINED_SLOW] =
[MCPE_MAKE_ALIGNED_WORD32_UNDEFINED_SLOW] =
"make_aligned_word32_undefined_slow",
[MCPE_MAKE_ALIGNED_WORD64_UNDEFINED] = "make_aligned_word64_undefined",
[MCPE_MAKE_ALIGNED_WORD64_UNDEFINED_SLOW] =
[MCPE_MAKE_ALIGNED_WORD64_UNDEFINED_SLOW] =
"make_aligned_word64_undefined_slow",
[MCPE_MAKE_ALIGNED_WORD32_NOACCESS] = "make_aligned_word32_noaccess",
[MCPE_MAKE_ALIGNED_WORD32_NOACCESS_SLOW] =
@ -7469,7 +7473,7 @@ static void done_prof_mem ( void )
if (MC_(event_ctr)[i] > 0) {
spaced = False;
++n;
VG_(printf)( "prof mem event %3d: %11llu %s\n",
VG_(printf)( "prof mem event %3d: %11llu %s\n",
i, MC_(event_ctr)[i],
MC_(event_ctr_name)[i]);
}
@ -8054,7 +8058,7 @@ static void mc_post_clo_init ( void )
// uninitialized, but in practice will retain previous contents [zero in
// this case.]"
//
// In short:
// In short:
//
// A key property of sbrk/brk is that new whole pages that are supplied
// by the operating system *do* get initialized to zero.
@ -8123,7 +8127,7 @@ static void mc_post_clo_init ( void )
// Activate full xtree memory profiling.
VG_(XTMemory_Full_init)(VG_(XT_filter_1top_and_maybe_below_main));
}
}
static void print_SM_info(const HChar* type, Int n_SMs)
@ -8147,19 +8151,19 @@ static void mc_print_stats (void)
n_sanity_cheap, n_sanity_expensive );
VG_(message)(Vg_DebugMsg,
" memcheck: auxmaps: %llu auxmap entries (%lluk, %lluM) in use\n",
n_auxmap_L2_nodes,
n_auxmap_L2_nodes * 64,
n_auxmap_L2_nodes,
n_auxmap_L2_nodes * 64,
n_auxmap_L2_nodes / 16 );
VG_(message)(Vg_DebugMsg,
" memcheck: auxmaps_L1: %llu searches, %llu cmps, ratio %llu:10\n",
n_auxmap_L1_searches, n_auxmap_L1_cmps,
(10ULL * n_auxmap_L1_cmps)
/ (n_auxmap_L1_searches ? n_auxmap_L1_searches : 1)
);
(10ULL * n_auxmap_L1_cmps)
/ (n_auxmap_L1_searches ? n_auxmap_L1_searches : 1)
);
VG_(message)(Vg_DebugMsg,
" memcheck: auxmaps_L2: %llu searches, %llu nodes\n",
n_auxmap_L2_searches, n_auxmap_L2_nodes
);
);
print_SM_info("n_issued ", n_issued_SMs);
print_SM_info("n_deissued ", n_deissued_SMs);
@ -8176,7 +8180,7 @@ static void mc_print_stats (void)
// Note that the pool allocator has some additional small overhead
// which is not counted in the below.
// Hardwiring this logic sucks, but I don't see how else to do it.
max_secVBit_szB = max_secVBit_nodes *
max_secVBit_szB = max_secVBit_nodes *
(3*sizeof(Word) + VG_ROUNDUP(sizeof(SecVBitNode), sizeof(void*)));
max_shmem_szB = sizeof(primary_map) + max_SMs_szB + max_secVBit_szB;
@ -8195,13 +8199,13 @@ static void mc_print_stats (void)
if (MC_(clo_mc_level) >= 3) {
VG_(message)(Vg_DebugMsg,
" ocacheL1: %'14lu refs %'14lu misses (%'lu lossage)\n",
stats_ocacheL1_find,
stats_ocacheL1_find,
stats_ocacheL1_misses,
stats_ocacheL1_lossage );
VG_(message)(Vg_DebugMsg,
" ocacheL1: %'14lu at 0 %'14lu at 1\n",
stats_ocacheL1_find - stats_ocacheL1_misses
- stats_ocacheL1_found_at_1
stats_ocacheL1_find - stats_ocacheL1_misses
- stats_ocacheL1_found_at_1
- stats_ocacheL1_found_at_N,
stats_ocacheL1_found_at_1 );
VG_(message)(Vg_DebugMsg,
@ -8320,7 +8324,7 @@ static void mc_fini ( Int exitcode )
mc_print_stats();
if (0) {
VG_(message)(Vg_DebugMsg,
VG_(message)(Vg_DebugMsg,
"------ Valgrind's client block stats follow ---------------\n" );
show_client_block_stats();
}
@ -8395,7 +8399,7 @@ static void mc_pre_clo_init(void)
MC_(__builtin_vec_delete),
MC_(__builtin_vec_delete_aligned),
MC_(realloc),
MC_(malloc_usable_size),
MC_(malloc_usable_size),
MC_MALLOC_DEFAULT_REDZONE_SZB );
MC_(Malloc_Redzone_SzB) = VG_(malloc_effective_client_redzone_size)();
@ -8408,12 +8412,12 @@ static void mc_pre_clo_init(void)
// mc_new_mem_mmap.
VG_(track_new_mem_mmap) ( mc_new_mem_mmap );
VG_(track_change_mem_mprotect) ( mc_new_mem_mprotect );
VG_(track_copy_mem_remap) ( MC_(copy_address_range_state) );
VG_(track_die_mem_stack_signal)( MC_(make_mem_noaccess) );
VG_(track_die_mem_stack_signal)( MC_(make_mem_noaccess) );
VG_(track_die_mem_brk) ( MC_(make_mem_noaccess) );
VG_(track_die_mem_munmap) ( MC_(make_mem_noaccess) );
VG_(track_die_mem_munmap) ( MC_(make_mem_noaccess) );
/* Defer the specification of the new_mem_stack functions to the
post_clo_init function, since we need to first parse the command
@ -8431,7 +8435,7 @@ static void mc_pre_clo_init(void)
VG_(track_die_mem_stack_160) ( mc_die_mem_stack_160 );
# endif
VG_(track_die_mem_stack) ( mc_die_mem_stack );
VG_(track_ban_mem_stack) ( MC_(make_mem_noaccess) );
VG_(track_pre_mem_read) ( check_mem_is_defined );

View File

@ -204,6 +204,13 @@ typedef
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
0, 2, 0, 0, 0)
/* Same as VALGRIND_DO_LEAK_CHECK but only showing new entries
i.e. loss records that were not there in the previous leak
search. */
#define VALGRIND_DO_NEW_LEAK_CHECK \
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \
0, 3, 0, 0, 0)
/* Do a summary memory leak check (like --leak-check=summary) mid-execution. */
#define VALGRIND_DO_QUICK_LEAK_CHECK \
VALGRIND_DO_CLIENT_REQUEST_STMT(VG_USERREQ__DO_LEAK_CHECK, \

View File

@ -22,7 +22,7 @@ $SED "s/checked [0-9,]* bytes./checked ... bytes./" |
# More leak check filtering. For systems that do extra libc allocations
# (eg. Darwin) there may be extra (reachable, and thus not shown) loss
# records. So we filter out the loss record numbers.
perl -p -e "s/in loss record \d+ of \d+/in loss record ... of .../" |
perl -p -e "s/in (?:new )?loss record \d+ of \d+/in loss record ... of .../" |
# Filter out glibc debuginfo if installed.
perl -p -e "s/\(syscall-template.S:[0-9]*\)/(in \/...libc...)/" |

View File

@ -6,6 +6,7 @@
char *b10;
char *b21;
char *b32_33[2];
char *b42_43[2];
static void breakme() {};
void f(void)
{
@ -47,7 +48,18 @@ void f(void)
b32_33[0]--;
fprintf(stderr, "expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable\n"); fflush(stderr); breakme();
VALGRIND_DO_CHANGED_LEAK_CHECK;
for (i = 0; i < 2; i ++)
b42_43[i] = malloc (42+i);
b42_43[0]--;
fprintf(stderr, "expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable\n"); fflush(stderr); breakme();
VALGRIND_DO_NEW_LEAK_CHECK;
b42_43[1]--;
fprintf(stderr, "expecting to have NO details\n"); fflush(stderr); breakme();
VALGRIND_DO_NEW_LEAK_CHECK;
fprintf(stderr, "finished\n");
}

View File

@ -1,89 +1,106 @@
expecting details 10 bytes reachable
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
expecting to have NO details
expecting details +10 bytes lost, +21 bytes reachable
10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
21 (+21) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:23)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:24)
by 0x........: main (leak-delta.c:72)
expecting details +65 bytes reachable
65 (+65) bytes in 2 (+2) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
expecting to have NO details
expecting details +10 bytes reachable
10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
expecting details -10 bytes reachable, +10 bytes lost
0 (-10) bytes in 0 (-1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
expecting details -10 bytes lost, +10 bytes reachable
0 (-10) bytes in 0 (-1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
10 (+10) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
expecting details 32 (+32) bytes lost, 33 (-32) bytes reachable
32 (+32) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
33 (-32) bytes in 1 (-1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
expecting details 42 (+42) bytes lost, 43 (+43) bytes reachable
42 (+42) bytes in 1 (+1) blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
43 (+43) bytes in 1 (+1) blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)
expecting to have NO details
finished
leaked: 32 bytes in 1 blocks
leaked: 117 bytes in 3 blocks
dubious: 0 bytes in 0 blocks
reachable: 64 bytes in 3 blocks
suppressed: 0 bytes in 0 blocks
10 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:14)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:15)
by 0x........: main (leak-delta.c:72)
21 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:23)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:24)
by 0x........: main (leak-delta.c:72)
32 bytes in 1 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
33 bytes in 1 blocks are still reachable in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:28)
by 0x........: main (leak-delta.c:60)
by 0x........: f (leak-delta.c:29)
by 0x........: main (leak-delta.c:72)
85 bytes in 2 blocks are definitely lost in loss record ... of ...
at 0x........: malloc (vg_replace_malloc.c:...)
by 0x........: f (leak-delta.c:53)
by 0x........: main (leak-delta.c:72)