@@ -50,6 +50,10 @@ struct BugpointPass : public Pass {
50
50
log (" -grep \" <string>\"\n " );
51
51
log (" only consider crashes that place this string in the log file.\n " );
52
52
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 " );
53
57
log (" -fast\n " );
54
58
log (" run `proc_clean; clean -purge` after each minimization step. converges\n " );
55
59
log (" faster, but produces larger testcases, and may fail to produce any\n " );
@@ -98,7 +102,7 @@ struct BugpointPass : public Pass {
98
102
log (" \n " );
99
103
}
100
104
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)
102
106
{
103
107
design->sort ();
104
108
@@ -107,7 +111,16 @@ struct BugpointPass : public Pass {
107
111
f.close ();
108
112
109
113
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 ;
111
124
}
112
125
113
126
bool check_logfile (string grep)
@@ -404,6 +417,8 @@ struct BugpointPass : public Pass {
404
417
void execute (std::vector<std::string> args, RTLIL::Design *design) override
405
418
{
406
419
string yosys_cmd = " yosys" , yosys_arg, grep, runner;
420
+ bool flag_expect_return = false , has_check = false ;
421
+ int expect_return_value = 0 ;
407
422
bool fast = false , clean = false ;
408
423
bool modules = false , ports = false , cells = false , connections = false , processes = false , assigns = false , updates = false , wires = false , has_part = false ;
409
424
@@ -430,9 +445,19 @@ struct BugpointPass : public Pass {
430
445
continue ;
431
446
}
432
447
if (args[argidx] == " -grep" && argidx + 1 < args.size ()) {
448
+ has_check = true ;
433
449
grep = args[++argidx];
434
450
continue ;
435
451
}
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
+ }
436
461
if (args[argidx] == " -fast" ) {
437
462
fast = true ;
438
463
continue ;
@@ -496,6 +521,9 @@ struct BugpointPass : public Pass {
496
521
if (yosys_arg.empty ())
497
522
log_cmd_error (" Missing -script or -command option.\n " );
498
523
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
+
499
527
if (!has_part)
500
528
{
501
529
modules = true ;
@@ -512,7 +540,10 @@ struct BugpointPass : public Pass {
512
540
log_cmd_error (" This command only operates on fully selected designs!\n " );
513
541
514
542
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 )
516
547
log_cmd_error (" The provided script file or command and Yosys binary do not crash on this design!\n " );
517
548
if (!check_logfile (grep))
518
549
log_cmd_error (" The provided grep string is not found in the log file!\n " );
@@ -525,29 +556,44 @@ struct BugpointPass : public Pass {
525
556
{
526
557
simplified = clean_design (simplified, fast, /* do_delete=*/ true );
527
558
528
- bool crashes;
529
559
if (clean)
530
560
{
531
561
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);
533
563
delete testcase;
534
564
}
535
565
else
536
566
{
537
- crashes = ! run_yosys (simplified, runner, yosys_cmd, yosys_arg);
567
+ retval = run_yosys (simplified, runner, yosys_cmd, yosys_arg);
538
568
}
539
569
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))
541
579
{
542
580
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
+ {
543
590
if (crashing_design != design)
544
591
delete crashing_design;
545
592
crashing_design = simplified;
546
593
found_something = true ;
547
594
}
548
595
else
549
596
{
550
- log (" Testcase does not crash.\n " );
551
597
delete simplified;
552
598
seed++;
553
599
}
0 commit comments