Problems launching openocd + GDB from Makefile - makefile

I'm trying to launch openocd + gdb via Make:
debug:
(openocd interface/stlink-v2.cfg -f target/stm32f4x.cfg &); \
arm-none-eabi-gdb $(BUILD_DIR)/$(TARGET).elf -ex "target remote localhost:3333" -ex "load"; \
killall openocd; \
This works until I press ctrl+c to break:
(gdb) c
Continuing.
^CError detected on fd 9
Remote communication error. Target disconnected.: Resource temporarily unavailable.
I'm guessing Make is intercepting the ctrl+c signal because if I copy the output of the debug command and paste it in my terminal (bash) I can break using ctrl+c without issues.
Is there a smart way to do this? I've tried wrapping the debug command in a shell script / python script, but haven't had any success

Related

Prevent sigint from closing OpenOCD when using OpenOCD with GDB

I am trying to write a script to launch OpenOCD in the background, and then launch and instance of GDB connected to my OpenOCD server. This mostly works, except that as soon as I type the interrupt character to halt the target I am debugging my OpenOCD server exits. It appears that OpenOCD is receiving SIGINT.
I have tried to separate OpenOCD from GDB in a number of different ways, at this point my script looks like this:
#! /bin/sh
trap '' SIGINT && nohup sh -c "trap '' SIGINT & openocd -f openocd-jlink.cfg < /dev/null" &
OPENOCD_PID=$!
arm-none-eabi-gdb -ex "set architecture armv6-m" -ex "target extended-remote localhost:2331" obj/main.elf
kill $OPENOCD_PID
I'm pretty sure that this should be very overkill yet OpenOCD still exits as soon as I type the interrupt character in GDB. If I run the same commands directly from my shell (not as part of script) everything works as expected. It works even if I just run openocd -f openocd-jlink.cfg & followed by GDB, no separate shell, nohup or trapping of SIGINT is required.
I'm hoping that someone might have an idea of what I can do in my script to prevent the SIGINT in GDB from reaching OpenOCD. Maybe there is some way to daemonize entirely from shell? I have read a lot of answers here about more generic issues with SIGINT in scripts, so I have a feeling this might be something specific to OpenOCD and GDB.
I have managed to solve this issue by using setsid. The working version of the script is:
#! /bin/sh
setsid openocd -f openocd-jlink.cfg -l /dev/null &
arm-none-eabi-gdbm" -ex "target extended-remote localhost:2331" obj/main.elf
killall openoc
Since I want the script to work on macOS as well as Linux and macOS does not ship with a setsid I ended up using Python to launch OpenOCD, which looks like this:
subprocess.Popen(["openocd", "-f", "openocd-jlink.cfg", "-l", "/dev/null"], preexec_fn = os.setsid)

How do I make Linux terminal shell out of these instructions?

I have been trying to make a .sh script using the instructions to run on the Raspberry Pi for the Atmel ATSAMD51G19A:
Launch openocd in a new terminal window:
sudo openocd -f openocdcfg.cfg
OpenOCD should stay running if it successfully connected to the device.
In a second terminal window, run the following:
gdb-multiarch AtmelStart.elf
Type these within gdb (say yes when prompted):
target remote :3333
lo
file User.elf
lo
mon reset
The display device should now be running the ncdisplay code.
Now I have no issues flashing the firmware onto the Atmel MCU. I only have issues when creating part 3 of the .sh script. So far, here is what my script looks like for part 3
(gdb) -ex target remote :3333
(gdb) -ex lo
(gdb) -ex file User.elf
(gdb) -ex y
(gdb) -ex y
(gdb) -ex lo
(gdb) -ex mon reset
(gdb) -ex q
None of the commands listed above will execute within gdb in terminal. I'm also unsure how to include 'y' for 'yes' within gdb when making a script. The terminal just stays idle waiting for the user to type a command.
I am still learning a lot about Linux and Debian/Ubuntu. In addition, this is the first time I have ever worked with gdb. Thank you for any help.
GDB takes a -x command line argument that allows you to pass in a set of commands to run, see https://sourceware.org/gdb/current/onlinedocs/gdb/File-Options.html#File-Options for more details.
So you can place your GDB commands into a separate file (lets call it cmd.gdb) and then do gdb-multiarch -x cmd.gdb AtmelStart.elf.
If GDB is processing commands from a command file then it will assume yes in answer to the yes/no prompts, so GDB will not stop.
If you do want to stick to using -ex then you can try adding this command to the start of your list -ex 'set confirm off' this should stop GDB asking you yes/no questions.

Inhibit SIGINT for the process in group

I have a bash script, which start 2 processes:
openocd ...flags... 2>openocd.log &
arm-none-eabi-gdb
When in gdb, interrupting execution with Ctrl+C causes openocd to receive SIGINT as well and, thus it stops. I've tried to trap and reissue SIGINT directly to gdb with:
trap 'kill 2 $!' INT
But apart from requiring root, it does not work anyway:
./dbg.sh: 1: kill: No such process
Are there elegant ways to perform the task?
__
Well, running script with debug options on helped a lot. But still I encounter weird behavior. Here is the content of my script:
#!/bin/sh
set -vx
trap 'killall -s2 arm-none-eabi-gdb-py' 2
openocd -f ...flags... 2>openocd.log & arm-none-eabi-gdb-py
When I run killall -s2 arm-none-eabi-gdb-py from within different tty - it terminates execution of remote target and does not close openocd, but sending SIGINT through Ctrl+C returns:
+ killall -s2 arm-none-eabi-gdb-py
arm-none-eabi-gdb-py: no process found
Seems like trap does not inhibit signals at all... changing to trap 'ps -ef' INT reveals, openocd AND gdb are already down when the trap command executes.
Isn't there a missing '&' in your instruction (it would give that)?
openocd -f ...flags... 2>openocd.log &**&** arm-none-eabi-gdb-py

Debugging GDB itself and signal handling issues

I am trying to debug GDB itself and dealing with a Ctrl+C signal problem that is sent from another terminal.
I run GDB to be debugged in terminal 1 in TUI mode. Right after, I open another terminal 2 and find the PID number of the GDB that runs on Terminal 1. Then attach that process to debug.
In Terminal 1
$ build-gdb/gdb/gdb -tui ./build/output.elf -tty=$TTY
In Terminal 2
$ ps -elf | less
$ sudo gdb -p PID_NUMBER-tty=$TTY -tui
The problem is when I hit Ctrl+C to stop GDB in terminal 1, GDB runs on Terminal 2 stops. GDB in Terminal 1 does not responds to ^C command at all. I tried to use -tty parameter and get the current TTY, but id did not solved the problem. GDB uses readline GNU library, but i should be configure terminal and its input properly.
Any idea?
You can use
handle SIGINT pass
to instruct GDB to pass the signal to the inferior. See Signals in the GDB manual. The nostop argument could be useful in this situation, too.

LLDB Restart process without user input

I am trying to debug a concurrent program in LLDB and am getting a seg fault, but not on every execution. I would like to run my process over and over until it hits a seg fault. So far, I have the following:
b exit
breakpoint com add 1
Enter your debugger command(s). Type 'DONE' to end.
> run
> DONE
The part that I find annoying, is that when I get to the exit function and hit my breakpoint, when the run command gets executed, I get the following prompt from LLDB:
There is a running process, kill it and restart?: [Y/n]
I would like to automatically restart the process, without having to manually enter Y each time. Anyone know how to do this?
You could kill the previous instance by hand with kill - which doesn't prompt - then the run command won't prompt either.
Or:
(lldb) settings set auto-confirm 1
will give the default (capitalized) answer to all lldb queries.
Or if you have Xcode 6.x (or current TOT svn lldb) you could use the lldb driver's batch mode:
$ lldb --help
...
-b
--batch
Tells the debugger to running the commands from -s, -S, -o & -O,
and then quit. However if any run command stopped due to a signal
or crash, the debugger will return to the interactive prompt at the
place of the crash.
So for instance, you could script this in the shell, running:
lldb -b -o run
in a loop, and this will stop if the run ends in a crash rather than a normal exit. In some circumstances this might be easier to do.

Resources