I'm trying to debug a remote device using gdbserver and IDA Pro. I'm attached to the correct PID and I'm able to step through instructions until the point where I redirect $pc to my ROP chain. At the jalr I get a SIGTRAP and the process crashes. My goal is to be able to trace through the shellcode outside of the loaded binary scope.

Is it possible with IDA Pro or do I need gdb on my client suitable for MIPS? if so where can I find a tutorial/explanation how to do so?

  • Not sure about IDA, but your GDB architecture must match the target. You can install arch-specific versions of gdb on ubuntu using apt, or use gdb-multiarch. If you want to examine the effects / execution of your ROP chain gdb sounds like the right tool.
    – jmcarter9t
    Commented Apr 10, 2021 at 13:27
  • have you checked that the address you are jumping to makes sense? maybe add the shellcode in the question and indicate where it crashes
    – gipi
    Commented Nov 28, 2022 at 9:29

2 Answers 2


What wersion gdbserver are you use? You make this gdbserver or download in repository. Please check file output for mips file (big or little endian) and also check output gdbserver -v Try connect gdb on your gdbserver and trace, if be successful, then problem in ida.


You should be able to use IDA to debug MIPS binaries. It's been a while for me, but I seem to recall IDA sometimes getting confused by the branch delay slot (the instruction following a jump/branch). If possible, set your breakpoint to whatever the jump target is rather than attempting to single step into the jalr.

Alternatively, you might be getting bitten by data/instruction cache incoherency. Are you triggering a cache flush/invalidation prior to jumping into your shellcode? If not and if this is in Linux userspace, ropping into sleep() should do the trick. This is because your shellcode starts out as data and sits in the data cache until it is flushed to main memory. Only when that happens can it be fetched from main memory as instructions. A sleep() allows the kernel to briefly context switch to another process, which requires a cache flush.

To do that you need to:

  1. Stage a small sleep period (1 or 2 seconds should suffice) into $a0
  2. Stage a return address into $ra
  3. Stage the address of sleep() someplace, probably $s0, where you can jr to it
  4. jr to whatever reg holds address of sleep()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.