{"record":{"id":"204b959bb88fd3d2","repo":"NationalSecurityAgency/ghidra","slug":"database-in-use-204b95","errorCode":null,"errorMessage":"database in use","messagePattern":"database in use","errorType":"exception","errorClass":"SQLException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2FileFunctionDatabase.java","lineNumber":128,"sourceCode":"\tprotected void createDatabase(Configuration config) throws SQLException {\n\t\ttry {\n\t\t\tsuper.createDatabase(config);\n\n\t\t\tConnection db = initConnection();\n\t\t\ttry (Statement st = db.createStatement()) {\n\t\t\t\tvectorTable.create(st);\n\t\t\t}\n\t\t}\n\t\tcatch (final SQLException err) {\n\t\t\tthrow new SQLException(\"Could not create database: \" + err.getMessage());\n\t\t}\n\t}\n\n\t@Override\n\tprotected void dropDatabase() throws SQLException {\n\n\t\tif (getStatus() == Status.Busy || fileDs.getActiveConnections() != 0) {\n\t\t\tthrow new SQLException(\"database in use\");\n\t\t}\n\n\t\tclose(); // close this instance\n\n\t\tif (!fileDs.exists()) {\n\t\t\t// ignore request and return\n\t\t\treturn;\n\t\t}\n\n\t\t// Connect to database and examine schema\n\t\tHashSet<String> tableNames = new HashSet<>();\n\t\ttry (Connection c = initConnection(); Statement st = c.createStatement()) {\n\t\t\ttry (ResultSet rs = st.executeQuery(\n\t\t\t\t\"SELECT table_name FROM information_schema.tables WHERE table_schema = 'public' ORDER BY table_name\")) {\n\t\t\t\twhile (rs.next()) {\n\t\t\t\t\ttableNames.add(rs.getString(1));\n\t\t\t\t}\n\t\t\t}","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/file/H2FileFunctionDatabase.java#L110-L146","documentation":"Thrown as an SQLException by H2FileFunctionDatabase.dropDatabase() when the database status is Busy or there are active connections to the H2 file data source. H2 file databases use file-level locking, so an active connection prevents safe deletion of the database file.","triggerScenarios":"Occurs when dropDatabase() is called while getActiveConnections() != 0 or getStatus() == Status.Busy. This happens when: another Ghidra instance or thread has the database open, a prior query hasn't released its connection, or the database is mid-operation.","commonSituations":"A second Ghidra window has the same H2 BSim database open. A long-running BSim query is in progress. The previous database connection wasn't properly closed (connection leak). Background tasks or headless scripts are still using the database.","solutions":["Close all other Ghidra instances or processes that have the database open.","Ensure all prior queries have completed and connections are released before calling dropDatabase().","Call database.close() on the current instance before attempting drop.","If connections are leaked, restart Ghidra to clear them.","On the file system level, check for stale H2 lock files (.lock.db) and remove them if no process is active."],"exampleFix":"// before\ndb.dropDatabase(); // throws 'database in use'\n\n// after\ndb.close(); // release this instance's connection\nint active = fileDs.getActiveConnections();\nif (active > 0) {\n    throw new IllegalStateException(\n        \"Cannot drop: \" + active + \" active connections remain\");\n}\ndb.dropDatabase();","handlingStrategy":"validation","validationCode":"// Check active connections before dropping\nif (database.getStatus() == Status.Busy) {\n    throw new IllegalStateException(\n        \"Database is Busy; wait for in-progress operations to finish\");\n}\nif (fileDs.getActiveConnections() != 0) {\n    throw new IllegalStateException(\n        fileDs.getActiveConnections() + \" active connections; close them first\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    database.dropDatabase();\n} catch (SQLException e) {\n    if (e.getMessage().equals(\"database in use\")) {\n        // Close this instance, wait, and retry\n        database.close();\n        Thread.sleep(2000);\n        database.dropDatabase();\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always call database.close() before dropDatabase().","Ensure no other Ghidra instance or script is using the database.","Check getActiveConnections() before attempting to drop.","Remove stale H2 lock files if no process is actually running."],"tags":["bsim","h2","database","drop","concurrency","locked"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}