Skip to content

hide specific variables in the counterexample trace for test-gen-support #605

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

Closed

Conversation

lucasccordeiro
Copy link
Contributor

hide variable assignments related to dynamic_object[0-9],
dynamic_[0-9]_array, and CPROVER internal functions
(e.g., __CPROVER_initialize). This PR is related to
test-gen-support issue https://github.com/diffblue/test-gen/issues/20

if (expr.id()==ID_symbol)
{
std::string identifier = expr.get(ID_identifier).c_str();
if (identifier.find("dynamic_")!=std::string::npos)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a hack...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I also agree that this looks like a hack. I was thinking about alternatives to get rid of this hack. What do you think if we create a new field called "dynamic_object" that is properly set during the convert method call in goto-programs? This might create some additional overhead when we build the respective goto-program.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the symbol behind that name, you should find #dynamic to be set in the type of the symbol. See goto-symex/symex_builtin_functions.cpp.

{
if (expr.id()==ID_symbol)
{
std::string identifier = expr.get(ID_identifier).c_str();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use id2string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented as suggested.

else
{
forall_operands(it, expr)
hide_dynamic_object(*it,goto_trace_step);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cpplint (more instances)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented as suggested.

@tautschnig
Copy link
Collaborator

Why is this hiding actually necessary?

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: We would like to hide all variable assignments in the counterexample trace related to

  • dynamic_object[0-9]
  • dynamic_[0-9]_array

I have tried to implement your suggestion as follows:

....
bool is_dynamic_object=expr.type().get_bool("#dynamic");
goto_trace_step.hidden=is_dynamic_object;
....

However, it does not work if we have expressions that contain "dynamic_object[0-9]". For "dynamic_[0-9]_array", it seems to work well.

This is the test program that I'm using:

public class Test
{
   public static void foo(int x, int y)
   {
     int diffblue[] = {10, 20, 30, 40};

     assert(diffblue[x] + diffblue[y] != x + y);
  }

   public static void main(String[] args)
   {
     foo(40,30);
   }
}

I'm running CBMC as follows:

cbmc Test.class --trace --json-ui

@tautschnig
Copy link
Collaborator

I believe you will need to look up the symbol in the namespace and then look at the symbol's type. Comments like #dynamic need not be present in all expressions. Could you give that a try?

@lucasccordeiro
Copy link
Contributor Author

Yes, sure. I'll take a look at it.

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: I have tried to look for examples in the source code, but I couldn't find what you have suggested (maybe I have misunderstood it). Is there some chance to point to some particular portion of the CBMC code, where I could look at your suggestion?

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: It seems that expressions like dynamic_object[0-9] and dynamic_[0-9]_array are not in the symbol table. If I understood your comment correctly, I have tried to look for the symbol in the namespace as follows:

...
  if(expr.id()==ID_symbol)
  {
    symbol_tablet symbol_table = ns.get_symbol_table();

    if (symbol_table.has_symbol(to_symbol_expr(expr).get_identifier()))
    {
      const symbolt &symbol=
        ns.lookup(to_symbol_expr(expr));
     }
   ...
   }
...

However, I'm unable to look further at the symbol's type since the second if-condition is always false.

I have also run CBMC with the option ''--show-symbol-table'', but I was unable to find expressions like dynamic_object[0-9] and dynamic_[0-9]_array in the symbol table.

s_it2=goto_trace.steps.erase(s_it2));

s_it2=goto_trace.steps.erase(s_it2))
{ };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you are touching this code: I believe this can be rewritten to goto_trace.steps.erase(s_it1, goto_trace.steps.end()); instead of this strange for loop.

Copy link
Contributor Author

@lucasccordeiro lucasccordeiro Mar 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented as suggested.

@tautschnig
Copy link
Collaborator

Indeed you wouldn't find them using --show-symbol-table as they will only be generated during symbolic execution.
You will want to use to_ssa_expr(expr).get_object_name() as you are likely dealing with some SSA-renamed symbol. That resulting name, I believe, should be found in the symbol table. If you still can't find it, would you mind printing out the exact identifier and copying this into the conversation here?

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: I have tried to implement your suggestion as:

  if(expr.id()==ID_symbol)
  {
    symbol_tablet symbol_table = ns.get_symbol_table();
    if (symbol_table.has_symbol(to_ssa_expr(expr).get_object_name()))
    {
      const symbolt &symbol=
        ns.lookup(to_symbol_expr(expr));
      ...
     }
  }

However, we get this in the trace:

identifier __CPROVER_rounding_mode!0#1 not found

In json format:

{
  "messageText": "identifier __CPROVER_rounding_mode!0#1 not found",
  "messageType": "ERROR"
}

@tautschnig
Copy link
Collaborator

I am sorry, I had misguided you: you need get_original_name, not get_object_name.

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: I still get the same behavior as previously mentioned if I replace "get_object_name" by "get_original_name". Do you have another suggestion?

- strip <CR> from end of lines in test.pl
- tests for test-script do not depend on gcc
- Makefile in regression/goto-analyser has the same structure as other test Makefiles
- remove tests for empty lines
@tautschnig
Copy link
Collaborator

Would you mind adding expr.pretty() for debugging purposes (and copy the final tree output in here)?

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: yes, sure. Find below the output of expr.pretty() method:

expr.pretty(): symbol
  * type: signedbv
      * width: 32
      * #c_type: signed_int
  * identifier: __CPROVER_rounding_mode!0#1
  * expression: symbol
      * type: signedbv
          * width: 32
          * #c_type: signed_int
      * identifier: __CPROVER_rounding_mode
  * L0: 0
  * L2: 1
  * L1_object_identifier: __CPROVER_rounding_mode!0
  * #SSA_symbol: 1
,
{
  "messageText": "identifier __CPROVER_rounding_mode!0#1 not found",
  "messageType": "ERROR"
}

@tautschnig
Copy link
Collaborator

Ok, this looks good - there might be a minor omission in your code; the following should work:

if(expr.id()==ID_symbol)
  {
    symbol_tablet symbol_table = ns.get_symbol_table();
    if (symbol_table.has_symbol(to_ssa_expr(expr).get_original_name()))
    {
      const symbolt &symbol=
        ns.lookup(to_ssa_expr(expr).get_original_name());  // <-- this had still been to_symbol_expr ...
      ...
     }
  }

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: I have used get_original_name() for both calls: has_symbol and lookup as follows:

  if(expr.id()==ID_symbol)
  {
    symbol_tablet symbol_table = ns.get_symbol_table();
    if (symbol_table.has_symbol(to_ssa_expr(expr).get_original_name()))
    {
      const symbolt &symbol=
        ns.lookup(to_ssa_expr(expr).get_original_name());
     }
  }
```

I'm now able to have access to the symbol's type, but it does not 
seem to show the dynamic object type. How can you detect whether 
a given symbol's type is dynamic?

Find attached the log file produced for the output of the goto trace 
using the expr.pretty() method.
 
[log.txt.zip](https://github.com/diffblue/cbmc/files/857729/log.txt.zip)

@lucasccordeiro
Copy link
Contributor Author

@tautschnig: many thanks for your support to fix this issue.

@peterschrammel: Now I believe we have a proper fix for this issue.

Let me know if you have further comments.

Daniel Kroening and others added 21 commits March 23, 2017 14:28
Correct pretty-printing of code_returnt
The default behaviour of CBMC for the options --show-goto-functions,
--show-properties and --cover is to consider all functions. This
is particularly annoying for --cover where coverage goals are
reported from functions that are trivially unreachable from the entry point.
Also, --show-reachable-properties has been introduced in the past
to hide such properties.
We could change the default behaviour to slicing away everything
that is trivially unreachable from the entry point. However, this would
require an extra option to be able to view all functions and properties.
This commit preserves the default behaviour and enables focussing
the output of --show-goto-functions --show-properties and --cover
on functions that are not trivially unreachable using --drop-unused-functions.
The same effect can now be achieved by
--show-properties --drop-unused-functions
…le-fun-only

Cover (and others) for reachable functions only
This commit changes the behahaviour of --no-assertions so that
only user assertions are ignored.
Built-in assertions can be hidden by the new option
--no-built-in-assertions.
skip_classid was always false, so there wasn't any point having it.
gen_nondet_init() is only used once, and is only two lines long,
so get rid of it and just put those two lines. This also avoids
confusion with java_object_factory::gen_nondet_init().
Do not slice away array_copy expressions during the implicit call
in the full-slicert class. We do not process array_copy in value_set_fit.
…ay_copy

added two test cases related to array copy in the goto-instrument
regression suite to further test the full-slice option
consider array_copy expressions in the full-slice
Updates to compiling instructions for GCC 6
…-object-factory

Cleanup/java object factory
…-user-only

No-assertions should not affect assertions in built-ins
hide variable assignments related to dynamic_object[0-9],
dynamic_[0-9]_array, and CPROVER internal functions
(e.g., __CPROVER_initialize). This PR is related to
test-gen-support issue diffblue#20
@lucasccordeiro
Copy link
Contributor Author

Due to several merge conflicts, I have created a new PR to address this issue: #709

NathanJPhillips pushed a commit to NathanJPhillips/cbmc that referenced this pull request Sep 6, 2018
…-webgoat

SEC-608: Add extra rule for StringBuilder::append(String)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants