Forgive my lack of experience here. I’m trying to debug a Cortex M0 MCU (Atmel SAMD21), and I’m not sure how to get lldb
to start.
I’ve got an OpenOCD debugger that I can flash from an ELF file. For now that was built with gcc from the Arduino IDE. I’ve successfully flashed these in the past using OpenOCD.
Now I’m trying to use OpenOCD as a debug server, and lldb as the client. I’ve done the following:
(lldb) history
0: file /var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf
1: platform select remote-gdb-server
2: platform connect connect://localhost:3333
But when I try process launch
, I get
(lldb) process launch
error: Bad CPU type in executable
What’s the right way to debug a target like this?
This is with a recent build of lldb
installed via Machomebrew.
On the microcontroller targets I’ve seen you have some out of band way to kick things off (e.g. serial connection to a bootloader), and then use lldb process connect
(usually via the gdb-remote
alias) to interface once it’s in a suitable state.
I suspect the process launch
is trying to run an ARMv6M binary on the host machine. Generally it seems far too concerned about properly-hosted OS features (env, stdin/out, argv) to be what you want.
I’ve already got the “process” running. For example, I used the Arduino IDE to build the blinking LED example, and flashed that onto the board. The LED blinks.
I then connect with:
$ lldb /var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf
$ lldb /var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf
(lldb) target create "/var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf"
Current executable set to '/var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf' (arm).
(lldb) target list
Current targets:
* target #0: /var/folders/16/jfb809_s2fz01ql7k494f6pc0000gn/T/arduino_build_98039/Blink.ino.elf ( arch=arm-*-*-eabi, platform=host )
(lldb) platform select remote-gdb-server
Platform: remote-gdb-server
Connected: no
(lldb) platform connect connect://localhost:3333
Platform: remote-gdb-server
Hostname: (null)
Connected: yes
(lldb) l
44 TinyUSB_Device_Init(0);
45 #elif defined(USBCON)
46 USBDevice.init();
47 USBDevice.attach();
48 #endif
49
50 setup();
51
52 for (;;)
53 {
(lldb) c
(lldb) n
error: Command requires a process which is currently stopped.
How do I get lldb to accept that there’s a “process?”
A bit more googling turned up gdb-remote
:
(lldb) platform disconnect
(lldb) gdb-remote 3333
Process 1 stopped
* thread #1, stop reason = signal SIGINT
frame #0: 0x00002280 Blink.ino.elf`micros at delay.c:54:13
51 ticks=ticks2;
52 pend=pend2;
53 count=count2;
-> 54 ticks2 = SysTick->VAL;
55 pend2 = !!(SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) ;
56 count2 = _ulTickCount ;
57 } while ((pend != pend2) || (count != count2) || (ticks < ticks2));
I wonder what that’s doing differently.
In any case, I still don’t really know how to get it to reset the processor and stop at the beginning of the program.
This was said before, but “launch” would have to know how to start something running, that’s its job. Of course, until you give it a target machine (in lldb’s terms a “platform”) to talk to then lldb can’t launch anything. “gdb-remote” creates the platform by connecting to the gdb-remote stub at the given IP address. The gdb-remote command follows the connection with queries to stub to see what’s there. If on connection the stub reports a process already running, lldb attaches to it. If there’s not something running, and the stub supports the “launch a process” packet, lldb will use that to implement the “launch” command (after the initial platform connection). But it looks like that isn’t supported in your scenario, and anyway, there IS already something running. So gdb-remote is the right thing to do in your case.
Jim
Okay, thanks. Now if I could just get breakpoints to work.