aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-08-07 16:11:32 +0200
committerAleksandr Nogikh <nogikh@google.com>2024-08-07 18:47:26 +0000
commit0f953f8412252770b055ec18242ea8d9b6cb0034 (patch)
treedb0beef8e72b496bd34c91a5e14e96e061ce7cd3 /prog
parent7013cb0d7d7b78bb0160c45d13a8d7d472835513 (diff)
prog: don't minimize int/resource for corpus
It makes little sense to minimize int's for corpus. Also replacing resource with a default value does not make sense as well. For corpus we are only interesting in reducing total number of args that will be considered for mutation. Add CrashSnapshot mode, mainly to keep the minimization code "alive" for now.
Diffstat (limited to 'prog')
-rw-r--r--prog/expr_test.go5
-rw-r--r--prog/minimization.go9
-rw-r--r--prog/minimization_test.go8
3 files changed, 14 insertions, 8 deletions
diff --git a/prog/expr_test.go b/prog/expr_test.go
index 6b767cd11..aaae6a74a 100644
--- a/prog/expr_test.go
+++ b/prog/expr_test.go
@@ -135,6 +135,7 @@ func TestEvaluateConditionalFields(t *testing.T) {
func TestConditionalMinimize(t *testing.T) {
tests := []struct {
+ mode MinimizeMode
input string
pred func(*Prog, int) bool
output string
@@ -156,6 +157,7 @@ func TestConditionalMinimize(t *testing.T) {
output: `test$conditional_struct(&(0x7f0000000040)={0x6, @value, @value=0x123})`,
},
{
+ mode: MinimizeCrashSnapshot,
input: `test$conditional_struct_minimize(&(0x7f0000000040)={0x1, @value=0xaa, 0x1, @value=0xbb})`,
pred: func(p *Prog, _ int) bool {
return bytes.Contains(p.Serialize(), []byte("0xaa"))
@@ -163,6 +165,7 @@ func TestConditionalMinimize(t *testing.T) {
output: `test$conditional_struct_minimize(&(0x7f0000000040)={0x1, @value=0xaa})`,
},
{
+ mode: MinimizeCrashSnapshot,
input: `test$conditional_struct_minimize(&(0x7f0000000040)={0x1, @value=0xaa, 0x1, @value=0xbb})`,
pred: func(p *Prog, _ int) bool {
return bytes.Contains(p.Serialize(), []byte("0xbb"))
@@ -186,7 +189,7 @@ func TestConditionalMinimize(t *testing.T) {
assert.NoError(tt, err)
p, err := target.Deserialize([]byte(test.input), Strict)
assert.NoError(tt, err)
- p1, _ := Minimize(p, 0, MinimizeCorpus, test.pred)
+ p1, _ := Minimize(p, 0, test.mode, test.pred)
res := p1.Serialize()
assert.Equal(tt, test.output, strings.TrimSpace(string(res)))
})
diff --git a/prog/minimization.go b/prog/minimization.go
index 935c18232..5f138feb4 100644
--- a/prog/minimization.go
+++ b/prog/minimization.go
@@ -39,6 +39,9 @@ const (
// Minimize crash reproducer.
// This mode assumes each test is expensive (need to reboot), so tries fewer things.
MinimizeCrash
+ // Minimize crash reproducer in snapshot mode.
+ // This mode does not assume that tests are expensive, and tries to minimize for reproducer readability.
+ MinimizeCrashSnapshot
// Only try to remove calls.
MinimizeCallsOnly
)
@@ -264,7 +267,7 @@ func (typ *ArrayType) minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool
elem := a.Inner[i]
elemPath := fmt.Sprintf("%v-%v", path, i)
// Try to remove individual elements one-by-one.
- if ctx.mode == MinimizeCorpus && !ctx.triedPaths[elemPath] &&
+ if ctx.mode != MinimizeCrash && !ctx.triedPaths[elemPath] &&
(typ.Kind == ArrayRandLen ||
typ.Kind == ArrayRangeLen && uint64(len(a.Inner)) > typ.RangeBegin) {
ctx.triedPaths[elemPath] = true
@@ -307,7 +310,7 @@ func (typ *ProcType) minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool {
func minimizeInt(ctx *minimizeArgsCtx, arg Arg, path string) bool {
// TODO: try to reset bits in ints
// TODO: try to set separate flags
- if ctx.mode == MinimizeCrash {
+ if ctx.mode != MinimizeCrashSnapshot {
return false
}
a := arg.(*ConstArg)
@@ -335,7 +338,7 @@ func minimizeInt(ctx *minimizeArgsCtx, arg Arg, path string) bool {
}
func (typ *ResourceType) minimize(ctx *minimizeArgsCtx, arg Arg, path string) bool {
- if ctx.mode == MinimizeCrash {
+ if ctx.mode != MinimizeCrashSnapshot {
return false
}
a := arg.(*ResultArg)
diff --git a/prog/minimization_test.go b/prog/minimization_test.go
index 7862bcc01..6a3fb4e4e 100644
--- a/prog/minimization_test.go
+++ b/prog/minimization_test.go
@@ -52,7 +52,7 @@ func TestMinimize(t *testing.T) {
// Aim at removal of sched_yield.
return len(p.Calls) == 2 && p.Calls[0].Meta.Name == "mmap" && p.Calls[1].Meta.Name == "pipe2"
},
- "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x0, 0x10, 0xffffffffffffffff, 0x0)\n" +
+ "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
"pipe2(0x0, 0x0)\n",
1,
},
@@ -87,7 +87,7 @@ func TestMinimize(t *testing.T) {
func(p *Prog, callIndex int) bool {
return p.String() == "mmap-write-sched_yield"
},
- "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x0, 0x10, 0xffffffffffffffff, 0x0)\n" +
+ "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
"write(0xffffffffffffffff, 0x0, 0x0)\n" +
"sched_yield()\n",
2,
@@ -103,7 +103,7 @@ func TestMinimize(t *testing.T) {
func(p *Prog, callIndex int) bool {
return p.String() == "mmap-write-sched_yield"
},
- "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x0, 0x10, 0xffffffffffffffff, 0x0)\n" +
+ "mmap(&(0x7f0000000000/0x1000)=nil, 0x1000, 0x3, 0x32, 0xffffffffffffffff, 0x0)\n" +
"write(0xffffffffffffffff, 0x0, 0x0)\n" +
"sched_yield()\n",
-1,
@@ -148,7 +148,7 @@ func TestMinimize(t *testing.T) {
"minimize$0(0x1, 0x1)\n",
-1,
func(p *Prog, callIndex int) bool { return len(p.Calls) == 1 },
- "minimize$0(0x1, 0xffffffffffffffff)\n",
+ "minimize$0(0x1, 0x1)\n",
-1,
},
// Clear unneeded fault injection.