Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Binary file not shown.
Binary file not shown.
183 changes: 183 additions & 0 deletions examples/callgraph/java-maven-minimal/CALLGRAPH_OUTPUT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Callgraph Output Analysis

This document explains the `debricked-call-graph.java` file generated by running the sample project.

## Output Format

The callgraph output is a **JSON file** containing the complete static call graph for the Java project.

### Top-level Structure

```json
{
"version": "5",
"data": [
[ /* method entry 1 */ ],
[ /* method entry 2 */ ],
...
]
}
```

### Method Entry Format

Each method in the `data` array is represented as:

```
[
methodSignature, // 0: Full method signature
isUserCode, // 1: Boolean - is this user-written (true) or library (false)
isNative, // 2: Boolean - is this a native method
className, // 3: Class name
sourceFile, // 4: Source file path
lineNumber, // 5: Method definition line number
unknown, // 6: Unused field (-1)
callers // 7: Array of caller entries
]
```

### Caller Entry Format

Each caller in the method's `callers` array is:

```
[
callerMethodSignature, // Who calls this method
callLineNumber, // At which line they call it
unknown // Direction marker ("-")
]
```

## Example: Tracing a Call Path

From the sample app, here's how to trace a call:

**App.main() calls OrderService.placeOrder():**

```json
"com.example.callgraph.OrderService.placeOrder(String, int, double)" → [
// ... other fields ...
[
[
"com.example.callgraph.App.main(String[])", // Called by App.main
8, // At line 8
"-"
]
]
]
```

**OrderService.placeOrder() calls PricingService.calculateTotal():**

```json
"com.example.callgraph.PricingService.calculateTotal(int, double)" → [
// ... other fields ...
[
[
"com.example.callgraph.OrderService.placeOrder(String, int, double)",
11, // At line 11
"-"
]
]
]
```

**PricingService.calculateTotal() calls applyDiscount():**

```json
"com.example.callgraph.PricingService.applyDiscount(double)" → [
// ... other fields ...
[
[
"com.example.callgraph.PricingService.calculateTotal(int, double)",
6, // At line 6
"-"
]
]
]
```

## Full Call Chain in Sample

```
App.main(String[])
↓ (line 5)
PricingService.<init>()

App.main(String[])
↓ (line 6)
OrderService.<init>(PricingService)

App.main(String[])
↓ (line 8)
OrderService.placeOrder(String, int, double)
↓ (line 11)
PricingService.calculateTotal(int, double)
↓ (line 6)
PricingService.applyDiscount(double)

App.main(String[])
↓ (line 9)
LoggerUtil.log(String)
↓ (line 10)
StringUtils.upperCase(String)
↓ (line 9348)
String.toUpperCase()
```

## Key Fields Explained

| Field | Meaning | Example |
|-------|---------|---------|
| `methodSignature` | Full qualified method with params | `com.example.callgraph.App.main(String[])` |
| `isUserCode` | `true` for app code, `false` for libraries/JDK | `true` for our classes, `false` for JDK |
| `isNative` | `true` for native methods | `true` for `Object.registerNatives()` |
| `className` | Fully qualified class name | `com.example.callgraph.App` |
| `sourceFile` | Relative path to .java file or `-` for JDK | `com/example/callgraph/App.java` |
| `lineNumber` | Line where method is defined | `4` |
| `callers[i][0]` | Method that calls this method | Same signature format |
| `callers[i][1]` | Line number of the call site | `8` |

## Understanding the Data Flow

1. **Find a method** by searching for its signature in the data array
2. **See who calls it** by looking at the `callers` field (index 7)
3. **Find those callers** by searching for them in the data array
4. **Repeat** to build the full call chain

## Practical Use Cases

### Find all methods called from App.main()

Search for `"com.example.callgraph.App.main(String[])"` then extract caller entries where `App.main` appears in the callers.

### Find all methods that call a specific method

Search the data array and look for methods that have the target method in their callers list.

### Identify library usage

Look for methods with `isUserCode: false` to understand which external libraries/JDK methods are being called.

### Analyze reachability

Starting from `main()`, trace through all callers recursively to find all reachable methods.

## Soot Analysis Details

This callgraph was generated by **Soot** version 5.1, a static Java bytecode analysis framework that:

- Analyzes `.class` files (compiled Java bytecode)
- Builds a static call graph without running the code
- Includes both library and user code in the graph
- Works at the bytecode level, so can find method calls not obvious in source code

The wrapper processes:
- **User code**: From `target/classes/` (your compiled app)
- **Library code**: From `.debrickedTmpFolder/` (Maven dependencies)
- **JDK**: Auto-included in analysis

## File Size Note

The JSON can be quite large (especially with many dependencies) because it includes the complete transitive closure of all method calls, including deep library internals.

Loading
Loading