Skip to content

Commit 804e923

Browse files
bugpoint: Add -expect-return
Allows checking return value from crashing design. Makes it possible to only accept designs that crash with e.g. SEGFAULT. Based on `exec -expect-return`.
1 parent b3a8e4e commit 804e923

File tree

1 file changed

+54
-8
lines changed

1 file changed

+54
-8
lines changed

passes/cmds/bugpoint.cc

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ struct BugpointPass : public Pass {
5050
log(" -grep \"<string>\"\n");
5151
log(" only consider crashes that place this string in the log file.\n");
5252
log("\n");
53+
log(" -expect-return <int>\n");
54+
log(" only consider crashes that return the specified value. e.g. SEGFAULT\n");
55+
log(" returns a value of 139.\n");
56+
log("\n");
5357
log(" -fast\n");
5458
log(" run `proc_clean; clean -purge` after each minimization step. converges\n");
5559
log(" faster, but produces larger testcases, and may fail to produce any\n");
@@ -98,7 +102,7 @@ struct BugpointPass : public Pass {
98102
log("\n");
99103
}
100104

101-
bool run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg)
105+
int run_yosys(RTLIL::Design *design, string runner, string yosys_cmd, string yosys_arg)
102106
{
103107
design->sort();
104108

@@ -107,7 +111,16 @@ struct BugpointPass : public Pass {
107111
f.close();
108112

109113
string yosys_cmdline = stringf("%s %s -qq -L bugpoint-case.log %s bugpoint-case.il", runner.c_str(), yosys_cmd.c_str(), yosys_arg.c_str());
110-
return run_command(yosys_cmdline) == 0;
114+
auto status = run_command(yosys_cmdline);
115+
// we're not processing lines, which means we're getting raw system() returns
116+
if(WIFEXITED(status))
117+
return WEXITSTATUS(status);
118+
else if(WIFSIGNALED(status))
119+
return WTERMSIG(status);
120+
else if(WIFSTOPPED(status))
121+
return WSTOPSIG(status);
122+
else
123+
return 0;
111124
}
112125

113126
bool check_logfile(string grep)
@@ -404,6 +417,8 @@ struct BugpointPass : public Pass {
404417
void execute(std::vector<std::string> args, RTLIL::Design *design) override
405418
{
406419
string yosys_cmd = "yosys", yosys_arg, grep, runner;
420+
bool flag_expect_return = false, has_check = false;
421+
int expect_return_value = 0;
407422
bool fast = false, clean = false;
408423
bool modules = false, ports = false, cells = false, connections = false, processes = false, assigns = false, updates = false, wires = false, has_part = false;
409424

@@ -430,9 +445,19 @@ struct BugpointPass : public Pass {
430445
continue;
431446
}
432447
if (args[argidx] == "-grep" && argidx + 1 < args.size()) {
448+
has_check = true;
433449
grep = args[++argidx];
434450
continue;
435451
}
452+
if (args[argidx] == "-expect-return") {
453+
flag_expect_return = true;
454+
++argidx;
455+
if (argidx >= args.size())
456+
log_cmd_error("No expected return value specified.\n");
457+
458+
expect_return_value = atoi(args[argidx].c_str());
459+
continue;
460+
}
436461
if (args[argidx] == "-fast") {
437462
fast = true;
438463
continue;
@@ -496,6 +521,9 @@ struct BugpointPass : public Pass {
496521
if (yosys_arg.empty())
497522
log_cmd_error("Missing -script or -command option.\n");
498523

524+
if (flag_expect_return && expect_return_value == 0 && !has_check)
525+
log_cmd_error("Nothing to match on for -expect-return 0; change value or use -grep.\n");
526+
499527
if (!has_part)
500528
{
501529
modules = true;
@@ -512,7 +540,10 @@ struct BugpointPass : public Pass {
512540
log_cmd_error("This command only operates on fully selected designs!\n");
513541

514542
RTLIL::Design *crashing_design = clean_design(design, clean);
515-
if (run_yosys(crashing_design, runner, yosys_cmd, yosys_arg))
543+
int retval = run_yosys(crashing_design, runner, yosys_cmd, yosys_arg);
544+
if (flag_expect_return && retval != expect_return_value)
545+
log_cmd_error("The provided script file or command and Yosys binary returned value %d instead of expected %d on this design!\n", retval, expect_return_value);
546+
if (!flag_expect_return && retval == 0)
516547
log_cmd_error("The provided script file or command and Yosys binary do not crash on this design!\n");
517548
if (!check_logfile(grep))
518549
log_cmd_error("The provided grep string is not found in the log file!\n");
@@ -525,29 +556,44 @@ struct BugpointPass : public Pass {
525556
{
526557
simplified = clean_design(simplified, fast, /*do_delete=*/true);
527558

528-
bool crashes;
529559
if (clean)
530560
{
531561
RTLIL::Design *testcase = clean_design(simplified);
532-
crashes = !run_yosys(testcase, runner, yosys_cmd, yosys_arg);
562+
retval = run_yosys(testcase, runner, yosys_cmd, yosys_arg);
533563
delete testcase;
534564
}
535565
else
536566
{
537-
crashes = !run_yosys(simplified, runner, yosys_cmd, yosys_arg);
567+
retval = run_yosys(simplified, runner, yosys_cmd, yosys_arg);
538568
}
539569

540-
if (crashes && check_logfile(grep))
570+
bool crashes = false;
571+
if (flag_expect_return && retval == expect_return_value && check_logfile(grep))
572+
{
573+
log("Testcase matches expected crash.\n");
574+
crashes = true;
575+
}
576+
else if (!flag_expect_return && retval == 0)
577+
log("Testcase does not crash.\n");
578+
else if (!flag_expect_return && check_logfile(grep))
541579
{
542580
log("Testcase crashes.\n");
581+
crashes = true;
582+
}
583+
else
584+
// flag_expect_return && !(retval == expect_return_value && check_logfile(grep))
585+
// !flag_expect_return && !(retval == 0 && check_logfile(grep))
586+
log("Testcase does not match expected crash.\n");
587+
588+
if (crashes)
589+
{
543590
if (crashing_design != design)
544591
delete crashing_design;
545592
crashing_design = simplified;
546593
found_something = true;
547594
}
548595
else
549596
{
550-
log("Testcase does not crash.\n");
551597
delete simplified;
552598
seed++;
553599
}

0 commit comments

Comments
 (0)