{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Context\n", "\n", "In the recent stress test of our application GlugiZP2000, we had severe issues with data quality and program failures. After an initial inspection of our code review team, we found several spot in the application that can lead to race conditions.\n", "\n", "Race conditions are bad because they lead to weird behavior in multi-user applications. Wikipedia defines [Race Conditions](https://en.wikipedia.org/wiki/Race_condition) as follows:\n", "\n", "> A race condition or race hazard is the behavior of an electronics, software, or other system where the output is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when events do not happen in the order the programmer intended.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Idea\n", "Some of the occurred race conditions could be statically identified by our software expert John Doe. In the following analysis, we use [jQAssistant](https://jqassistant.org/) and the [Neo4j](https://neo4j.com/) graph database to spot even more possible problems with the help of structural code analysis. For this, we read in the complete Java code of GlugiZP2000 into the Neo4j database." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Analysis\n", "With the following Cypher queries, we can spot some kind of race conditions that are declared public and not static fields and are written by some methods." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%load_ext cypher" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3 rows affected.\n" ] }, { "data": { "text/html": [ "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
InClasstheMethodwritesInLinetoStaticField
BrokenSingletongetInstance11INSTANCE
OwnerControllerprocessFindForm110ownersIndexes
OwnerControllerprocessFindForm110ownersIndexes
" ], "text/plain": [ "[['BrokenSingleton', 'getInstance', 11, 'INSTANCE'],\n", " ['OwnerController', 'processFindForm', 110, 'ownersIndexes'],\n", " ['OwnerController', 'processFindForm', 110, 'ownersIndexes']]" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%cypher\n", "MATCH (c:Class)-[:DECLARES]->(f:Field)<-[w:WRITES]-(m:Method)\n", "WHERE \n", " EXISTS(f.static) AND NOT EXISTS(f.final)\n", "RETURN \n", " c.name as InClass, \n", " m.name as theMethod, \n", " w.lineNumber as writesInLine, \n", " f.name as toStaticField" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Conclusion\n", "There are some possible race conditions regarding static, written Java field references. Our suggestion is to fix these immediately." ] } ], "metadata": { "hide_input": false, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.4" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "toc_cell": false, "toc_position": {}, "toc_section_display": "block", "toc_window_display": false }, "varInspector": { "cols": { "lenName": 16, "lenType": 16, "lenVar": 40 }, "kernels_config": { "python": { "delete_cmd_postfix": "", "delete_cmd_prefix": "del ", "library": "var_list.py", "varRefreshCmd": "print(var_dic_list())" }, "r": { "delete_cmd_postfix": ") ", "delete_cmd_prefix": "rm(", "library": "var_list.r", "varRefreshCmd": "cat(var_dic_list()) " } }, "types_to_exclude": [ "module", "function", "builtin_function_or_method", "instance", "_Feature" ], "window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }