Skip to content

Feature/new instrumentation runtime exceptions #912

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

Conversation

cristina-david
Copy link
Collaborator

This PR introduces the flag --java-throw-runtime-exceptions such that, whenever used, instead of adding runtime exceptions instrumentation in the form of assertions, we actually throw the corresponding exceptions.

The only problem here is that some of the instrumentation for NullPointerException is added in goto_check.cpp, whereas the rest of the instrumentation is added earlier in java_bytecode_convert_method.cpp. In my opinion, we should do all the instrumentation before goto_check.cpp for two reasons: 1. the exceptions to be thrown are language specific; 2. we presumably don't want to instrument all the dereferences given that many are introduced by us, e.g. when accessing array->length, and they shouldn't throw an exception. Therefore, I've added all the exception throwing instrumentation, including that for null dereference, in java_bytecode_convert_method.cpp. For now, I didn't touch the instrumentation in goto_check.cpp, but I think it should be disabled whenever the --java-throw-runtime-exceptions flag is on. Otherwise, we introduce redundant instrumentation.

Copy link
Contributor

@thk123 thk123 left a comment

Choose a reason for hiding this comment

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

Looks good - seems to be missing at least a couple of test cases (I think ideally there would also be test cases for when --java-throw-runttime-execptions isn't enabled as it isn't clear what the expected behaviour is then.

const exprt &class2,
const source_locationt &original_loc)
{
// TODO: use std::move
Copy link
Contributor

Choose a reason for hiding this comment

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

To avoid having to fix this in 4 places - could a helper function get_exception(const irep_idt &exception_type) handle this logic?

}
else
{
const typecast_exprt lhs(op[0], pointer_typet(empty_typet()));
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a suggested change - but I don't really understand what the code looks like if throw_runtime_exceptions is disabled - perhaps some documentation (or maybe extract this also into a method so you can document in the name?)

check.add_source_location()
.set_property_class("array-create-negative-size");
checkandcreate.move_to_operands(check);
c=code_blockt();
Copy link
Contributor

Choose a reason for hiding this comment

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

One letter variable names aren't advised by the coding standard - perhaps something that explains what this code block does? array_index_read_block?

Copy link
Collaborator Author

@cristina-david cristina-david May 30, 2017

Choose a reason for hiding this comment

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

Yes, I agree. However, the c here is declared much earlier in the function (https://github.com/cristina-david/cbmc/blob/feature/new-instrumentation-runtime-exceptions/src/java_bytecode/java_bytecode_convert_method.cpp#L1454) and used to set the converted instruction. So, I would like to avoid changing it everywhere in this PR.

--java-throw-runtime-exceptions
^EXIT=0$
^SIGNAL=0$
^VERIFICATION SUCCESSFUL$
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if the test could test more than this - I don't know if this is possible on CBMC, but something that actually validates that CBMC has figured out a run time exception should be thrown

const exprt &length,
const source_locationt &original_sloc);

codet throw_null_dereference_exception(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see a test that validates this, unless this test does: NullPointerException1 but this is currently KNOWNBUG and doesn't enable the --throw-runtime-exceptions`.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've added NullPointerException2.

const exprt &expr,
const source_locationt &original_sloc);

codet throw_class_cast_exception(
Copy link
Contributor

Choose a reason for hiding this comment

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

Also missing a test as far as I can tell.

@@ -61,6 +61,7 @@ class optionst;
"(round-to-nearest)(round-to-plus-inf)(round-to-minus-inf)(round-to-zero)" \
"(graphml-witness):" \
"(java-max-vla-length):(java-unwind-enum-static)" \
"(java-throw-runtime-exceptions)" \
Copy link
Contributor

Choose a reason for hiding this comment

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

Missing help documentation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added.

Copy link
Contributor

@smowton smowton left a comment

Choose a reason for hiding this comment

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

Some correctness questions

{
exc_symbol.is_static_lifetime=true;
exc_symbol.base_name="ArrayIndexOutOfBoundsException";
exc_symbol.name="ArrayIndexOutOfBoundsException";
Copy link
Contributor

Choose a reason for hiding this comment

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

Surely this should have prefix java::java.lang.

const binary_relation_exprt lt_zero(idx, ID_lt, zero);
const member_exprt length_field(array_struct, "length", java_int_type());
const binary_relation_exprt ge_length(idx, ID_ge, length_field);
const and_exprt and_expr(lt_zero, ge_length);
Copy link
Contributor

Choose a reason for hiding this comment

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

Should be or_exprt I think? I believe this is testing for idx < 0 && idx >= arr.length

const source_locationt &original_loc)
{
symbolt exc_symbol;
if(!symbol_table.has_symbol("NegativeArraySizeException"))
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar qualifying of the name to above


code_ifthenelset if_code;
if_code.add_source_location()=original_loc;
if_code.cond()=ge_zero;
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar to above, this seems to throw if length >= 0?


code_ifthenelset if_code;
if_code.add_source_location()=original_loc;
if_code.cond()=and_expr;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think op != null && op instanceof Target -> op != null && !op instanceof Target

@cristina-david cristina-david force-pushed the feature/new-instrumentation-runtime-exceptions branch 4 times, most recently from 0df5a69 to 75bdc66 Compare May 30, 2017 14:54
@cristina-david cristina-david force-pushed the feature/new-instrumentation-runtime-exceptions branch 3 times, most recently from 9bcf8a4 to d6a4f3a Compare May 30, 2017 17:31
@cristina-david cristina-david force-pushed the feature/new-instrumentation-runtime-exceptions branch from d6a4f3a to 18714d5 Compare May 31, 2017 07:53
@cristina-david
Copy link
Collaborator Author

@thk123 I added more regression tests, including some that do not set the --java-throw-runtime-exceptions flag for NullPointerException and ClassCastException.

@cristina-david cristina-david force-pushed the feature/new-instrumentation-runtime-exceptions branch from ed4e2c3 to 20f8791 Compare May 31, 2017 09:41
@cristina-david
Copy link
Collaborator Author

@smowton and @thk123 Thanks for your comments, I think I've addressed all of them.

Copy link
Contributor

@smowton smowton left a comment

Choose a reason for hiding this comment

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

LGTM, just one possible change:

Since the old-style logic now largely duplicates the code in the functions that creates exceptions, could we factor that in? For example, could we rename throw_exception -> check_condition (bool use_exception, exprt cond), where check_condition either asserts !cond or generates if(cond) throw ... depending on the use_exception parameter?

@sara-db
Copy link

sara-db commented Jun 22, 2017

@cristina-david can this be merged? Already approved by @smowton and @thk123

@cristina-david
Copy link
Collaborator Author

This is now part of #1019 together with more refactoring so I'll close it here.

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.

4 participants