Skip to content

Add call depth indicator to Vp visual mode - #6815

Open
ThanSin02426 wants to merge 7 commits into
rizinorg:devfrom
ThanSin02426:feature/depth-indicator
Open

ThanSin02426 wants to merge 7 commits into
rizinorg:devfrom
ThanSin02426:feature/depth-indicator

Conversation

@ThanSin02426

Copy link
Copy Markdown

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description
This PR implements the "simple version" of the call-depth indicator requested in #6788.

The Vp visual disassembly view now shows a depth from <ref>: N indicator in the title bar, where N is the shortest number of calls between a user-configurable reference function and the function containing the cursor. When no path is known (e.g., due to indirect calls), it shows ???.

New config options:

  • graph.depth.enabled (bool, default false)
  • graph.depth.ref (string: flag name, hex address, or math expression)
  • graph.depth.max (int, default 20)

Design decisions:

  • Uses BFS on the function-level call graph .
  • Reference resolved via rz_num_math, so both main and 0x100000490 work.
  • Only CALL xrefs counted. Indirect calls (br x16) produce UNKNOWN xrefs and correctly fall through to ???.
  • Defensive guard skips xrefs with to == 0 or to == UT64_MAX.

Note on AI assistance: Claude is used only for test logic and to navigate through Rizin codebase.

...

Test plan
Manual verification

Built a small ARM64 test binary with chain main → sym.call. Ran:
```
./build/binrz/rizin/rizin test/bins/elf/analysis/armcall
```
Inside Rizin:
```
aaa
e graph.depth.enabled=true
e graph.depth.ref=main
s main
Vp
```
The title bar shows depth from main: 0. Seeking to sym.call shows depth from main: 1. Seeking to an address not inside any function shows depth from main: ???.

Indirect-call behaviour verified:
```
$ s sym.imp.puts
$ axt
(nofunc) 0x100000120 [UNKNOWN] udf sym.imp.puts
dbg._a 0x100000470 [CALL] bl sym.imp.puts
```
Confirms only direct CALL xrefs are traversed; indirect branches produce UNKNOWN xrefs and correctly result in ???.

Automated test

Added NAME=depth indicator simple chain in test/db/cmd/cmd_visual using the interactive mode pattern:
```
cd test
../build/binrz/rz-test/rz-test db/cmd/cmd_visual
```
Result: all 11 tests pass on darwin-arm64.

...

Closing issues
Closes #6788

...

@Rot127

Rot127 commented Sep 28, 2026

Copy link
Copy Markdown
Member

Forgot to mention it in the issue. Please add a video which shows how it works.

@ThanSin02426

Copy link
Copy Markdown
Author

Demo video

demo.mov

@ThanSin02426

Copy link
Copy Markdown
Author

@Rot127 please see if I am missing something.

Comment thread test/db/cmd/cmd_visual

@Rot127 Rot127 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like a good start!

One issue though.
It only works if the cursor is exactly at a function address:

[0xc09ee2ac [xAdvc]0 0% 285 vfile://0/modem.b08]> pd $r @ fcn.c09ee2ac depth from fcn.c09ee36c: 1                          
            ; CALL XREF from fcn.c09ee304 @ 0xc09ee30c                                                                     
            ; CALL XREF from fcn.c09ee36c @ 0xc09ee374                                                                     
┌ fcn.c09ee2ac();                                                                                                          
│           0xc09ee2ac      ┌   immext(##0xc09afd00)                                                                       
│           0xc09ee2b0      │   R16 = ##-0x3f6502c8                                                                        
│           0xc09ee2b4      └   memd(R29+#-0x10) = R17:16 ; allocframe(#0x8)                                               

Seeking only one instruction down shows ???

[0xc09ee2b0 [xAdvc]0 0% 285 vfile://0/modem.b08]> pd $r @ fcn.c09ee2ac+4 depth from fcn.c09ee36c: ???                      
│           0xc09ee2b0      │   R16 = ##-0x3f6502c8                                                                        
│           0xc09ee2b4      └   memd(R29+#-0x10) = R17:16 ; allocframe(#0x8)                                           

But it should still be 1.

Comment thread librz/core/tui/visual.c Outdated
Comment thread test/db/cmd/cmd_visual
Comment thread test/db/cmd/cmd_visual
Comment thread librz/core/cconfig.c Outdated
Comment thread librz/core/cgraph.c Outdated
Comment thread librz/core/cgraph.c Outdated
Comment thread librz/core/cconfig.c Outdated
@ThanSin02426

Copy link
Copy Markdown
Author

"Pull Request Labeler" error is unrelated ?
@Rot127 @wargio I have implemented the changes.
Also for the depth tests I switched to REGEXP_FILTER_OUT, is it correct here?

@github-actions github-actions Bot added the AI/LLM Partially or fully AI generated. Critical thinking is advised! label Oct 12, 2026
@Rot127 Rot127 removed the AI/LLM Partially or fully AI generated. Critical thinking is advised! label Oct 13, 2026
@Rot127

Rot127 commented Oct 13, 2026

Copy link
Copy Markdown
Member

Segfaults for me now on a basic test:

rizin /bins/ls
aa
e graph.depth=ref=main
s main
Vp
<press 1 to jump to function of a call>
segfaults

@github-actions github-actions Bot added the AI/LLM Partially or fully AI generated. Critical thinking is advised! label Oct 13, 2026
@ThanSin02426

Copy link
Copy Markdown
Author

Segfaults for me now on a basic test:

rizin /bins/ls
aa
e graph.depth=ref=main
s main
Vp
<press 1 to jump to function of a call>
segfaults

@Rot127 I am not able to reproduce the segfault locally on macOS (may be because malloc keeps freed blocks intact longer) however I pushed a fix which likely caused it. Can you please check it and help me upon this :)

@Rot127

Rot127 commented Oct 15, 2026

Copy link
Copy Markdown
Member

Can't reproduce the crash now.
But I can enter an endless loop.

I seek to main, stepped a few instructions down and then jumped to different call targets and went back with u.
The endless loop started when I jumped to a location which was not analyzed as function.

@ThanSin02426

Copy link
Copy Markdown
Author

Can't reproduce the crash now. But I can enter an endless loop.

I seek to main, stepped a few instructions down and then jumped to different call targets and went back with u. The endless loop started when I jumped to a location which was not analyzed as function.

Not able to get an infinite loop but yes when in Vp I pressed j multiple times and jumped to different call target then got a CPU spike on pressing u. This exists even with the feature off likely due to disasm renderer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI/LLM Partially or fully AI generated. Critical thinking is advised! panel rz-test RzCore visual

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add indicator in assembly browser how many jumps/calls the user is from a reference point.

3 participants