OpenOCD exit on breakpoint - stm32

I'm developing an application on an STM32F042.
I drive everything from a makefile, including my unit tests.
I use OpenOCD and ST-LINK to flash the target.
My unit tests run on the host and on the target.
The host unit test driver returns 0 from main() on success and non-zero on failure, so the makefile knows if the tests pass.
The makefile flashes and starts tests on the target, but doesn't know if they succeed or fail.
The embedded test application turns on a red LED for fail and green for pass, so I know--now I want to automate this step.
I want to set two breakpoints in the code, one in the failure handler and one at the end of main, and tell OpenOCD to exit with zero or non-zero status if it hits one or the other breakpoint.
So my question boils down to two specific ones:
To set a breakpoint, I need to know the PC value at a specific line of code. How do I get that value from the arm-gcc toolchain?
Can I configure OpenOCD to exit on specific breakpoints, and with specific status?

Here's what I ended up with. For each target unit test, I start an OpenOCD server and connect to it with gdb. Gdb runs a script that sets two breakpoints, one for success, one for failure. If it hits either breakpoint, it shuts down the OCD server and exits with a code that communicates success and failure to the shell. To run the same tests on the host, I simply compile them as regular executables.
Makefile:
# target unit test binaries
foo_tests.elf bar_tests.elf baz_tests.elf bop_tests.elf: unit_test_runner.ao
# disable optimization for target unit test driver to avoid optimizing
# away functions that serve as breakpoint labels
unit_test_runner.ao: CFLAGS += -O0 -g
# link target unit test binaries for semihosting
%_tests.elf: ARM_LDLIBS += -specs=rdimon.specs -lrdimon
# host unit test binaries
foo_tests bar_time_tests baz_tests bop_tests: unit_test_runner.o
# run target unit test binaries through gdb and OpenOCD; redirecting stderr
# leaves printf output from `assert()' clearly visible on the console
%.tut: %.elf
openocd -f interface/stlink-v2-1.cfg -f target/stm32f0x.cfg 2> $#.log &
gdb-multiarc -batch-silent -x tut.gdb $< 2> $#-gdb.log
# run host binary
%.run: %
./$*
tests: foo_tests.run bar_time_tests.run baz_tests.run bop_tests.run \
foo_tests.tut bar_time_tests.tut baz_tests.tut bop_tests.tut
tut.gdb:
target remote localhost:3333
monitor arm semihosting enable # let assert()'s printf() through
monitor reset halt
load
monitor reset init
break success # set breakpoint on function `sucess()'
commands # on hitting this bp, execute the following:
monitor shutdown # shutdown OpenOCD server
quit 0 # exit GDB with success code
end
break failure # set breakpoint on function `sucess()'
commands
monitor shutdown
quit 1 # exit GDB with failure code
end
continue
unit_test_runner.c:
#include <stdlib.h>
/* These two functions serve as labels where gdb can place
breakpoints. */
void success() {}
void failure() {}
/* Implementation detail for `assert()' macro */
void assertion_failure(const char *file,
int line,
const char *function,
const char *expression)
{
printf("assertion failure in %s:%d (%s): `%s'\n",
file, line, function, expression);
failure();
exit(1);
}
/* This function is necessary for ARM semihosting */
extern void initialise_monitor_handles(void);
int main(int argc, char* argv[])
{
#ifdef __arm__
initialise_monitor_handles();
#endif
tests(); /* client code implements this function */
success();
return 0;
}

Related

How to setup a conditional breakpoint with simics command?

It looks like Simics Eclipse can setup a conditional breakpoint, but I didn't find any condition parameters with break-* commands. Is that possible to setup the break condition with simics commands?
Another question is how can I setup dynamic printf with simics commands?
with gdb, I can use this to logging breakpoint hits, how can I do the same thing with simics?
(gdb) b malloc
(gdb) commands
> silent
> printf "malloc hit"
> cont
> end
(gdb)
Simics does not have conditional breakpoints in the built-in breakpoint commands. If you want to do something like that, write a script branch that waits for the breakpoint and then inspect the state. The commands are intentionally fairly basic.
What is a "dynamic printf" in this context?
It might be simpler to use Simics gdb-remote to connect a gdb debugger to Simics and use that to debug your target software.
To see all breakpoint hits, Simics will tend to write a message each time the breakpoint hit:
simics> bp.memory.break -x 0xffff0000 0x100000
Breakpoint 2: break on 'x' access to 0xffff_0000 len=1_048_576 in board.cell_context
simics> r
[board.cell_context] Breakpoint 2: board.cell_context 'x' access to v:0xfffffff0
simics> r
[board.cell_context] Breakpoint 2: board.cell_context 'x' access to v:0xfffffff1
simics> r
[board.cell_context] Breakpoint 2: board.cell_context 'x' access to v:0xfffffff2 len=2
If you want to act on a breakpoint hit, use a script to react and print whatever your want. Like this, for example. If a script branch picks up the breakpoint, Simics will not stop its execution.
simics> script-branch {
....... while(TRUE) {
....... bp.wait-for-breakpoint 2
....... echo (ptime)
....... }
....... }
2
simics> r
"board.mb.cpu0.core[0][0]"
[["board.mb.cpu0.core[0][0]", 8, 8, 4e-09]]
"board.mb.cpu0.core[0][0]"
[["board.mb.cpu0.core[0][0]", 9, 9, 4.5e-09]]
"board.mb.cpu0.core[0][0]"

Minimal TCP client-server: accept() never receives a connection?

I copied the example code for the book TCP/IP Sockets in C from http://cs.ecs.baylor.edu/~donahoo/practical/CSockets/winsock.html and got it to compile on MinGW (without warnings by changing clntLen from unsigned int to int and void main to int main).
$ gcc.exe -Wall -o TCPEchoServerWS TCPEchoServerWS.c HandleTCPClientWS.c DieWithErrorWS.c -lws2_32
$ gcc.exe -o TCPEchoClientWS TCPEchoClientWS.c DieWithErrorWS.c -lws2_32
When I run the executables the server but not the client triggers a Windows firewall notification.
$ ./TCPEchoServerWS.exe 5000
inside for loop
$ ./TCPEchoClientWS.exe 169.1.1.1 "Echo this" 5000
connect() failed: 10060
The from printf debugging
for (;;) /* Run forever */
{
printf("inside for loop");
clntLen = sizeof(echoClntAddr);
if ((clntSock = accept(servSock, (struct sockaddr *) &echoClntAddr, &clntLen)) < 0)
DieWithError("accept() failed");
printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));
it appears that the accept() never returns. I assume this is because it never has a connection to extract?? Any ideas please? I've also tried linking with -lwsock32, and disabling windows firewall.
It turns out that I was using the wrong IP (I just copied the one from the command it the book).
I just needed to use the IPv4 address from ipconfig as Remy suggested.

Where does dev_dbg writes log to?

In a device driver source in the Linux tree, I saw dev_dbg(...) and dev_err(...), where do I find the logged message?
One reference suggest to add #define DEBUG . The other reference involves dynamic debug and debugfs, and I got lost.
dev_dbg() expands to dynamic_dev_dbg(), dev_printk(), or no-op depending on the compilation flags.
#if defined(CONFIG_DYNAMIC_DEBUG)
#define dev_dbg(dev, format, ...) \
do { \
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
} while (0)
#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG, dev, format, ##arg)
#else
#define dev_dbg(dev, format, arg...) \
({ \
if (0) \
dev_printk(KERN_DEBUG, dev, format, ##arg); \
})
#endif
dynamic_dev_dbg() and dev_printk() call dev_printk_emit() which calls vprintk_emit().
This very same function is called in a normal mode when you just do a printk(). Just note here, that the rest functions like dev_err() will end up in the same function.
Thus, obviously, the buffer is all the same, i.e. kernel intrenal buffer.
The logged message at the end is printed to
Current console if kernel loglevel value (can be changed via kernel command line or via procfs) is high enough for certain message, here KERN_DEBUG.
Internal buffer which can be read by running dmesg command.
Note, data in 2 is kept as long as there still room in the buffer. Since it's limited and circular, newer data preempts old one.
Additional information how to enable Dynamic Debug.
First of all, be sure you have CONFIG_DYNAMIC_DEBUG=y in the kernel configuration.
Assume we would like to enable all debug prints in the built-in module with name 8250. To achieve that we simple add to the kernel command line the following 8250.dyndbg=+p.
If the same driver is compiled as loadable module we may either add options 8250 dyndbg to the modprobe configuration or to the shell command line when do it manually, like modprobe 8250 dyndbg.
More details are described in the Dynamic Debug documentation.
The "How certain debug prints are automatically enabled in linux kernel?" raises the question why some debug prints are automatically enabled and how DEBUG affects that when CONFIG_DYNAMIC_DEBUG=y. The answer is lying in the dynamic_debug.h and since it's used during compilation the _DPRINTK_FLAGS_DEFAULT defines the certain message appearence.
#if defined DEBUG
#define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
#else
#define _DPRINTK_FLAGS_DEFAULT 0
#endif
you can find dev_err(...) in kernel messages. As the name implies, dev_err(...) messages are error messages, so they will definitely be printed if the execution comes to that point. dev_dbg(...) are debug messages which are more generously used in the kernel driver code and they are not printed by default. So everything you have read about dynamic_debugging comes into play with dev_dbg(...).
There are several pre-conditions to have dynamic debugging working, below 1. and 2. are general preconditions for dynamic debugging. 3. and later are for your particular driver/module/subsystem and can be .
Dynamic debugging support has to be in your kernel config CONFIG_DYNAMIC_DEBUG=y. You may check if it is the case zgrep DYNAMIC_DEBUG /proc/config.gz
debugfs has to be mounted. You can check with sudo mount | grep debugfs and if not existing, you can mount with sudo mount -t debugfs /sys/kernel/debug
refer to dynamic_debugging and enable the particular file/function/line you are interested

UNIX 'diff' returns improperly when called using popen in main.c

I have a series of tests for a school project that involves building an assembler.
The tests use popen to catch the output of "make" and "./assembler" -- this is just so the output of these commands don't crowd the output of the test suite.
The problem is that the call to popen that executes "diff" returns a string inside the automated test suite, but not when I call it manually.
Here's the test suite code:
char buf1[256];
FILE* make;
FILE* assemble;
FILE *diff;
make = popen("make", "r");
assemble = popen("./assembler input/simple.s inter.txt out.txt", "r");
diff = popen("diff inter.txt out/ref/simple_ref.int", "r");
fgets(buf1, sizeof(buf1), diff);
printf("\nafter fgets simple -- strlen(buf) is %d\t buf is %s\n", strlen(buf1), buf1);
Here's the segment of the test suite output that corresponds with the above code:
after fgets simple -- strlen(buf) is 8 buf is 1,7c1,6
Here's the series of commands when called manually:
aweeeezy  ⋯  make
rm -f *.o assembler test-assembler core
gcc -g -std=gnu99 -Wall -o assembler assembler.c src/utils.c src/tables.c src/translate_utils.c src/translate.c
aweeeezy  ⋯  ./assembler input/simple.s inter.txt out.txt
Running pass one: input/simple.s -> inter.txt
Running pass two: inter.txt -> out.txt
Assembly operation completed successfully.
aweeeezy  ⋯  diff inter.txt out/ref/simple_ref.int
aweeeezy  ⋯  
When you use popen(), you're launching subprocesses which run at the same time as your program. In the code fragment you showed, the subprocesses will all be running around the same time without coordination.
To replicate the command line behavior, you want to wait until each subprocess is done; which is to say, call pclose() before moving to the next stages of your process. For examples, check something like "Pipes the easy way!" at http://www.tldp.org/LDP/lpg/node12.html

WinDbg: using commands for the condition in .if

WinDbg has the .if statement for conditional execution of commands:
.if (Condition) { Commands } .else { Commands }
For Condition, it's not possible to use WinDbg commands. Is there any indirect way of using commands for the condition, e.g. through pseudo registers?
Example task to accomplish:
If a logfile is already opened, do nothing. If no logfile is open, use .logopen /t /u /d
With .logfile, I can find out whether a log is open or not. But how to parse that output and how to assign the result to a pseudo register?
Any other way without pseudo registers is also welcome.
As the example may not seem very useful, consider the following tasks which can be automated by scripting or the .cmdtree window:
Loading the correct version of SOS, e.g. .if (lm m clr == clr) { .loadby sos clr } .elseif (lm m mscorwks == mscorwks) {.loadby sos mscorwks}
Things I always forget to do, e.g. .if (| == myprocess) {.childdbg 1; .sympath+ mydir}
I tested this and it loads the correct sos.dll if it finds clr in the list of modules:
.foreach (module {lm1m} ) { .if ($sicmp("${module}","clr") == 0) {.echo FOUND ${module}; .loadby sos.dll clr} }
You can easily extend it using .elsif and comparing module with "mscorwks".
As for checking for your process, I attached to calc.exe and ran | which gives me: . 0 id: 6bc attach name: C:\Windows\system32\calc.exe
I only want the last token so I can skip the first six by specifying /pS 6 to .foreach. The following uses a wildcard comparison for *calc.exe and if found, tells the debugger to debug child processes:
.foreach /pS 6 (token {|}) {.echo ${token}; .if($spat("${token}","*calc.exe") == 1) {.echo FOUND MY APP;.childdbg 1} .else {.echo FAILED TO FIND MY APP} }
Also tested and worked.
ps. my debugger version is 6.2.8400.0