{"record":{"id":"48ae2bac03a7fd97","repo":"NationalSecurityAgency/ghidra","slug":"database-does-not-track-callgraph-48ae2b","errorCode":null,"errorMessage":"Database does not track callgraph","messagePattern":"Database does not track callgraph","errorType":"exception","errorClass":"LSHException","httpStatus":null,"severity":"warning","filePath":"Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java","lineNumber":2710,"sourceCode":"\t\t}\n\t\tRowKeyElastic eKey = RowKeyElastic.parseExeIdString(exeId);\n\t\tStringBuilder buffer = new StringBuilder();\n\t\teKey.generateLibraryFunctionId(buffer, funcName);\n\t\treturn buffer.toString();\n\t}\n\n\t/**\n\t * For every function currently in the manager, fill in its call-graph information.\n\t * This involves querying the database for child information, adding the cross-link\n\t * information (CallgraphEntry) between FunctionDescriptions, and possibly querying\n\t * for new library executables and functions\n\t * @param manager is the collection of functions to link\n\t * @throws LSHException for problems updating the container\n\t * @throws ElasticException for communication problems with the server\n\t */\n\tprivate void queryCallgraph(DescriptionManager manager) throws LSHException, ElasticException {\n\t\tif (!info.trackcallgraph) {\n\t\t\tthrow new LSHException(\"Database does not track callgraph\");\n\t\t}\n\t\tTreeMap<RowKey, FunctionDescription> funcmap = new TreeMap<>();\n\t\tmanager.generateFunctionIdMap(funcmap);\n\t\tfor (ExecutableRecord exeRec : manager.getExecutableRecordSet()) {\n\t\t\tif (exeRec.isLibrary()) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tList<FunctionDescription> funclist = new ArrayList<>();\n\t\t\tIterator<FunctionDescription> iter = manager.listFunctions(exeRec);\n\t\t\twhile (iter.hasNext()) { // Build a static copy of the list of functions\n\t\t\t\tfunclist.add(iter.next());\n\t\t\t}\n\t\t\tfor (FunctionDescription element : funclist) {\n\t\t\t\tfillinChildren(element, manager, funcmap);\n\t\t\t}\n\t\t}\n\t}\n","sourceCodeStart":2692,"sourceCodeEnd":2728,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java#L2692-L2728","documentation":"Thrown as an LSHException in queryCallgraph when info.trackcallgraph is false. The database was created without the callgraph tracking bit set in its settings, so call-graph relationship data was never stored. queryCallgraph is invoked by queries that request call-graph fill-in; if the database does not track callgraphs, the operation is unsupported.","triggerScenarios":"Calling queryCallgraph (triggered by QueryNearest or other commands that request call-graph population) when the DatabaseInformation.trackcallgraph field is false. The check happens at the top of queryCallgraph before any network queries are issued.","commonSituations":"Database created with default settings that do not include the callgraph tracking flag; querying an existing database that was intentionally created without callgraph support to save space; settings mismatch between client expectation and database configuration.","solutions":["Check database.getInfo().trackcallgraph before issuing callgraph-related queries and skip gracefully if false.","Recreate the database with callgraph tracking enabled by setting the appropriate settings flag during the generate/create command.","Avoid requesting callgraph data (e.g., set the callgraph fill-in option to false) when the database does not support it."],"exampleFix":"// before\ndatabase.query(query);  // internally calls queryCallgraph, throws LSHException\n\n// after\nif (database.getInfo() != null && database.getInfo().trackcallgraph) {\n    database.query(query);\n} else {\n    Msg.warn(this, \"Database does not track callgraph; skipping callgraph query\");\n}","handlingStrategy":"validation","validationCode":"// Check callgraph support before issuing callgraph queries\nif (!database.getInfo().trackcallgraph) {\n    Msg.warn(this, \"Database does not track callgraph; callgraph data will not be populated.\");\n    // Skip callgraph request or set query option to not request callgraph\n    query.fillcallgraph = false; // disable callgraph in the query\n}","typeGuard":null,"tryCatchPattern":"try {\n    database.query(query);\n} catch (LSHException e) {\n    if (e.getMessage().equals(\"Database does not track callgraph\")) {\n        Msg.warn(this, \"Callgraph not tracked — disable callgraph request and retry\");\n        query.fillcallgraph = false;\n        database.query(query); // retry without callgraph\n    } else {\n        throw e;\n    }\n}","preventionTips":["Check database.getInfo().trackcallgraph before requesting callgraph data.","Create databases with callgraph tracking enabled if callgraph queries are needed.","Make callgraph fill-in optional in query logic so it can be skipped gracefully."],"tags":["bsim","callgraph","configuration","feature-flag","settings"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}