7

I'm trying to debug an embedded project using remote GDB. My system:

  • Target: ARM Cortex M0.
  • SEGGER J-Link GDB Server V6.10 Command Line Version
  • arm-none-eabi-gdb 7.10.1.20160616-cvs
  • CLion 2016.2.2, Build #CL-162.1967.7
  • Ubuntu 16.04

I have the following in my .gdbinit file:

target remote localhost:2331 #(I remove this line when debugging with CLion)
set verbose on
file "/path_to_output_file/blinky.elf"
monitor reset
break main

The thing that has troubled me for days now, is that this works fine if I debug with gdb directly from a terminal, but not when I use the debugger in CLion. In CLion I get the error:

"monitor" command not supported by this target.

My theory is that the terminal accepts the "monitor reset" command (at least it doesn't complain). CLion on the other hand, prints an error, but appears to move on afterwards without doing the reset. The consequence seems to be that when I start a new debugging session in CLion I don't start at the beginning of main().

Is CLion blocking the monitor commands? If so, then why and is there a workaround?

I have the feeling that my questions might be related to CPP-7322 and CPP-7256.

Frant
  • 3,769
  • 1
  • 11
  • 20
bad_coffee
  • 137
  • 2
  • 8

2 Answers2

10

CLion doesn't block any particular command from .gdbinit on purpose. The thing is, these commands are executed on the debugger startup, before attaching to the target. That means that the monitor reset command gets executed without a remote session being run yet, hence it fails.

Just to clarify:

  • here's what happens when you execute GDB manually:

    # commands from .gdbinit
    target remote localhost:2331
    set verbose on
    file "/path_to_output_file/blinky.elf"
    monitor reset
    break main
    
  • here's what happens when you execute GDB from CLion with the same .gdbinit file:

    # commands from .gdbinit
    target remote localhost:2331
    set verbose on
    file "/path_to_output_file/blinky.elf"
    monitor reset
    break main
    
    # commands executed by CLion to attach
    target remote localhost:2331  # <- ERROR (A program is being debugged already)
    
  • and here's what's going on when you execute GDB from CLion with the attach command removed:

    # commands from .gdbinit
    set verbose on
    file "/path_to_output_file/blinky.elf"
    monitor reset  # <- ERROR not attached to remote gdbserver => unknown command
    
    # ... not executed due to the error above
    break main
    # commands executed by CLion to attach
    target remote localhost:2331
    

The issues you linked are totally the right ones, please feel free to vote (disclaimer: I'm one of CLion developers). I couldn't come up with a reasonable workaround to suggest you for now, I'm afraid.

Update:

There actually is a workaround for your use case that works for both CLion and terminal debug sessions. You can use GDB hooks to achieve that.

In your .gdbinit file replace the commands in question with the following lines:

define target hookpost-remote
file "/path_to_output_file/blinky.elf"
monitor reset
break main
end

This way, every time the remote target is connected, the GDB will execute the commands specified in the defined hook, regardless the way you start the debugger, either from CLion or from a terminal.

Rolf
  • 6,554
  • 4
  • 34
  • 52
Eldar Abusalimov
  • 21,255
  • 4
  • 60
  • 66
  • Then I don't understand why it works when I'm running arm-none-eabi-gdb directly from the terminal? Isn't it basically the same mechanisms? I can see in CLion's GDB terminal that there is a python call and I guess this is just some pretty-printing stuff? Then I get: /home/martin/.gdbinit:6 Error in sourced command file: "monitor" command not supported by this target I think it is weird that I get the "not supported" message if the issue is really the order of commands and executions. – bad_coffee Oct 03 '16 at 12:48
  • By the way; My current workaround is a script that resets and halts the chip using JLink before it starts the GDB server. Then I finally run the debugger from CLion. It is a hassle though, as it requires me to start and stop the script on each debug session. – bad_coffee Oct 03 '16 at 12:58
  • @bad_coffee I tried to explain the reasons of the errors you get, please review the updated answer. – Eldar Abusalimov Oct 03 '16 at 13:09
  • When reading the CPP-7322 description and your answer again I think I understood it. From the description: "So in my case, "target remote" is run two times: First when my .gdbinit is sourced, and second by CLion". In other words, .gdbinit is kind of overruled by CLion? And fixing CPP-7322 would solved the issue? – bad_coffee Oct 03 '16 at 13:09
  • @bad_coffee Yes, when CLion runs GDB, the latter sources `~/.gdbinit`, if any, and some commands like `target remote` can interfere and conflict with those executed by CLion afterwards. CPP-7322 indeed would solve the issue, your use case seems to be quite common. – Eldar Abusalimov Oct 03 '16 at 13:15
  • Thank you very much. Your edit makes perfect sense. I have voted on the issues. – bad_coffee Oct 03 '16 at 13:16
  • @bad_coffee please check if a workaround in the updated question works for you. – Eldar Abusalimov Oct 04 '16 at 13:28
  • I tried your suggestion and it got me one step further. It definitely seems like the .gdbinit is executed at the appropriate time. My problem now though, is that "monitor reset" both resets and halts my target CPU. And there I am stuck. I can use the "continue" command after reset and my application runs to the first breakpoint. However, it just lingers there for about 3 seconds while the "Variable" window in CLion says "Collecting data...". Then the GDB Server closes the connection and the debug session ends. – bad_coffee Oct 04 '16 at 18:18
  • I also tried your suggested .gdbinit once, then commented out "monitor reset", and ran it once more. Then debugging worked like it should. And I'm curious about why you have put the "end" command at the end? – bad_coffee Oct 04 '16 at 18:26
  • @bad_coffee `end` just terminates the `define` command, please refer to https://sourceware.org/gdb/onlinedocs/gdb/Hooks.html – Eldar Abusalimov Oct 04 '16 at 18:47
  • Thank you. I have examined the output in the JLink GDB Server's terminal. With your workaround it seems to be more or less exactly the same whether I debug in CLion or use GDB manually. However, as I mentioned above CLion is still stalling at the first breakpoint for about 3 seconds while the "Variable" pane in the Debug tool window in CLion says "Collecting data...". Then JLink GDB Server outputs "GDB closed TCP/IP connection". I get no errors or warnings. Do you think this is a CLion issue? – bad_coffee Oct 06 '16 at 11:40
  • @bad_coffee I'm not sure I can explain what is happening, I'm afraid. And I don't have a board on my hands to reproduce your case, unfortunately. Dunno, maybe there is a "`load`" command missing after the "`file`"? – Eldar Abusalimov Oct 06 '16 at 12:12
  • "load" didn't help, but thanks for your help anyway. I'll investigate further on my own. – bad_coffee Oct 07 '16 at 08:49
1

Looking around for the exact same issue, I came across this GitHub project that has a great step-by-step guide on setting up a JLink debugger on CLion. What really helped me out is the script that generates the .gdbinit in the user home directory.

There is no need to add a file /firmware.elf command as this is taken care of by CLion when a debug session is launched. On the other hand, a load command is necessary to flash your target.

jfmorin
  • 57
  • 7