-
-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fuzz testing #1038
Comments
Second part of log:
|
Hi @avelure! Your patch is not accessible anmore. Did you change it to private? Would be very interested in looking at your fuzzing setup. |
Sorry, I had forgotten to set the repo public. Should work now. |
I can reproduce the error from file package foo_pkg is
end foo_pkg;
package body foo_pkg is
shared variable var : integer;
package bar_pkg is
end bar_pkg;
package body bar_pkg is
shared variable var : integer;
end package body bar_pkg;
end package body foo_pkg; nvc crash log
Edit: Files that trigger the same crash:
|
I can reproduce the error from file package foo is
alias TO_OCTAL_STRING is ns;
end package foo; nvc crash log
|
The You might want to try disabling LLVM while you're doing this (
And with
So ~4x faster. |
Reproducer for error from file ENTITY next_ent IS
END next_ent;
ARCHITECTURE arch OF next_ent IS
TYPE integer_array IS ARRAY (NATURAL RANGE <>) OF INTEGER;
FUNCTION func1(ia: integer_array := (1,2,3,next)) RETURN BOOLEAN;
BEGIN
END ARCHITECTURE arch; Edit: Files that trigger the same crash:
|
Reproducer for error from file library ieee;
use ieee.std_logic_1164.all;
entity GENERIC_WHEN is
generic( FOO : std_logic_vector(1 downto 0) );
port( IN1 : in std_logic_vector(1 downto 0);
OUT1 : out std_logic_vector(1 downto 0) );
end GENERIC_WHEN;
architecture BEHAVIOUR of GENERIC_WHEN is
begin
process( IN1 )
begin
case IN1 is
when FOO => OUT1 <= FOO;
when others => null;
end case;
end process;
end BEHAVIOUR; @nickg I don't really know how that should be fixed. The following dirty hack works, but I'm unsure what effects it causes in the depths of other codepaths. diff --git a/src/common.c b/src/common.c
index 3b6d24b5..bebd594d 100644
--- a/src/common.c
+++ b/src/common.c
@@ -1599,7 +1599,10 @@ unsigned get_case_choice_char(tree_t value, int depth)
case T_REF:
{
tree_t decl = tree_ref(value);
- assert(tree_kind(decl) == T_CONST_DECL || tree_kind(decl) == T_ALIAS);
+ tree_kind_t kind = tree_kind(decl);
+ if (kind == T_GENERIC_DECL)
+ return ~0;
+ assert(kind == T_CONST_DECL || kind == T_ALIAS);
assert(tree_has_value(decl));
return get_case_choice_char(tree_value(decl), depth);
} |
Reproducer for error from file package timing_pkg is
type frequency is range real'high;
end package; |
Reproducer for error from file package foo is
end package;
package body foo is
procedure bar is
begin
report "" ; natural ;
end procedure;
end package body; Note: That line is very long. |
Reproducer for error from file package numeric_system_pkg is
impure function foo
end package;
architecture behav of hello is
begin
subtype sub is up'att another;
end package; Note: This is wholly not valid VHDL. |
I've done this now so you can try adding |
All but one hang seems to have been resolved with #1065. Hang from file library ieee;
use ieee.std_logic_1164.all;
package hang is
constant c0 : std_logic_vector (31 downto 0) := 32sb"1"; -- ok
constant c1 : std_logic_vector (31 downto 0) := 33333333333333332sb"1"; -- hangs
end package; |
I don't see an easy fix for the parser hang. The bit string literal seems to be valid and allowed according to the standard. Maybe we can at least add a warning? E.g.: diff --git a/src/parse.c b/src/parse.c
index 58ee05c1..0f59e37a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -675,6 +675,11 @@ static tree_t bit_string_to_literal(const char *str, const loc_t *loc)
return t;
}
+ // sanity check to warn of parser hang
+ if (length > 1000000)
+ warn_at(loc, "bit string literal with a length of %i seems erroreously "
+ "large, nvc might hang", length);
+
tree_t *bits LOCAL = NULL;
if (length >= 0)
bits = xmalloc_array(length, sizeof(tree_t)); |
There's various places where I limit arrays to if (length > INT32_MAX) {
error_at(loc, "sorry, bit strings longer than %d elements are not supported", INT32_MAX);
return t;
} |
I ran the fuzzing for a week and collected 32 crashing cases.
crashes_cmin.zip
There might be some duplicates in here as there often is different code paths that lead to the same crash.
The log below shows SIGABRT, but you can ignore this as this is because it is neceseary to modify the source to raise a signal to the fuzzer when something interesting occurs. You can see my patch here: https://github.com/avelure/vhdl_fuzz/blob/main/nvc_bug_abort.patch
Second part of log comes in a new comment as there is a comment length limit.
There was also one that causes an
input buffer overflow, can't enlarge buffer because scanner uses REJECT
, but that might not be so interesting.input_buffer_overflow.zip
Then there were 5 cases that seem to hang the parser or the parser takes an abnormal long time to complete.
hangs.zip
Currently I'm just using the analyze switch for fuzzing which is a bit slow. I guess I could use the
--syntax
switch to parse the file, but it is missing some of the analysis switches like--psl
,--relaxed
and--error-limit
, though it seems quite easy to add, so maybe I can make a pullrequest.Another option is to use persistence mode to loop the parser and just change the input buffer to speed up the testing https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md
this also seems feasible in nvc, so I can look at this next.
The text was updated successfully, but these errors were encountered: