I'm using STM32H745ZI Nucleo board with STLinkV3. I have successfully compiled and run simple program that flashes LEDs on Cortex M7 core. When program runs without debugger, everything's fine.
The problem appears while degugging. When I set breakpoint on line that turns the LED on, debugger stops in this place. The problem is that once stopped, continue and step over aren't working until the breakpoint is unset.
Code isn't much complicated:
while (1) {
LD1_SET(1);
HAL_Delay(100);
LD2_SET(1);
HAL_Delay(100);
LD3_SET(1);
HAL_Delay(100);
LD1_SET(0);
HAL_Delay(100);
LD2_SET(0);
HAL_Delay(100);
LD3_SET(0);
HAL_Delay(100);
}
This is how it looks like in gdb console:
# Setting breakpoint on LED ON
(gdb) b main.c:166
Breakpoint 1 at 0x8001788: file Src/main.c, line 166.
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
# Hit! Debugger seems working, LED is still OFF
Breakpoint 1, main () at Src/main.c:166
166 LD1_SET(1);
(gdb) c
Continuing.
# Hit the same breakpoint with no blinking between
Breakpoint 1, main () at Src/main.c:166
166 LD1_SET(1);
# Setting breakpoint on LED OFF
(gdb) b main.c:174
Breakpoint 2 at 0x80017c6: file Src/main.c, line 174.
(gdb) c
Continuing.
# Still hits LED ON, LED is still OFF
Breakpoint 1, main () at Src/main.c:166
166 LD1_SET(1);
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x08001788 in main at Src/main.c:166
breakpoint already hit 3 times
2 breakpoint keep y 0x080017c6 in main at Src/main.c:174
# Removing breakpoint on LED ON
(gdb) del 1
(gdb) c
Continuing.
# LED is ON, prorgram finally hit next breakpoint
Breakpoint 2, main () at Src/main.c:174
174 LD1_SET(0);
How to make it work? Have you experienced similar problem before?
Related
I am trying to debug two instances of the same application. Therefore I setup as followed:
(gdb) set target-async on
(gdb) set non-stop on
(gdb) attach pid1
(gdb) set scheduler-locking off
(gdb) add-inferior
(gdb) inferior 2
(gdb) attach pid2
(gdb) set scheduler-locking off
(gdb) b hello-world.cpp:8
Breakpoint 1 at 0x557a557761fd: ../hello-world.cpp:8. (2 locations)
(gdb) continue
The Problem I have is that only the currently selected inferior is continued. Is there a way to let all inferiors continue with one command?
Solution:
It works if the following sequnce is used:
(gdb) attach pid1
(gdb) add-inferior
(gdb) inferior 2
(gdb) attach pid2
(gdb) set schedule-multiple on
(gdb) b hello-world.cpp:8
Breakpoint 1 at 0x557a557761fd: ../hello-world.cpp:8. (2 locations)
(gdb) continue
Thanks to Klaus!
To continue all attached processes you have to set the scheduler mode in gdb.
set scheduler-locking off
A continue now let all threads continue.
For a detailed description of scheduler mode take a look here
As you ask in the comments what the complete procedure was:
(gdb) attach <pid 1>
(gdb) add-inferior
(gdb) inferior 2
(gdb) attach <pid 2>
(gdb) set scheduler-locking off
(gdb) b myprog.cpp:55
Why is GDB not able to see my local variable i ?
I am debugging a multi-process application running on an embedded linux device.
I am having a hard time attaching to a child process (note that I cannot start the child process by itself, it needs the parent to run it. )
Using set follow-fork-mode child did not work (gdb hangs while loading dynamic libraries).
My strategy is to have this in my code to stop the child
#ifdef DEBUG
int i = 0;
while (i == 0)
{
usleep(100000); // sleep for 0.1 seconds
}
#endif // DEBUG
To have time to attach to the child using gdbserver --attach :1234 <child-pid> and then, after setting a break point where I want (line 200 in main.cpp), to issue the following command in gdb : set var i = 1 to break out of the while loop.
This isn't working and I am wondering why. Here is the output from gdb:
(gdb) bt
#0 0x00007ff3feab7ff0 in nanosleep () from target:/lib/libc.so.6
#1 0x00007ff3feae1c14 in usleep () from target:/lib/libc.so.6
#2 0x000055cc4e56908a in main (argc=<optimized out>, argv=<optimized out>)
at platform/aas/intc/ucmclient/src/main.cpp:195
(gdb) break main.cpp:200
Breakpoint 1 at 0x55cc4e56908c: file platform/aas/intc/ucmclient/src/main.cpp, line 200.
(gdb) set var i=1
No symbol "i" in current context.
The backtrace seems to show I am in the while loop. Why then is the variable i not in the locals?
I have a server/client system that runs well on my machines. But it core dumps at one of the users machine (OS: Centos 5). Since I don't have access to the user's machine so I built a debug mode binary and asked the user to try it. The crash did happened again after around 2 days of running. And he sent me the core dump file. Loading the core dump file with gdb, it did shows the crash location but I don't understand the reason (sorry, my previous experience is mostly with Windows. I don't have much experience with Linux/gdb). I would like have your input. Thanks!
1. the /var/log/messages at the user's machine shows the segfault:
Jan 16 09:20:39 LPZ08945 kernel: LSystem[4688]: segfault at 0000000000000000 rip 00000000080e6433 rsp 00000000f2afd4e0 error 4
This message indicates that there is a segfault at instruction pointer 80e6433 and stack pointer f2afd4e0. Looks that the program tries to read/write at address 0.
2. load the core dump file into gdb and it shows the crash location:
$gdb LSystem core.19009
GNU gdb (GDB) CentOS (7.0.1-45.el5.centos)
... (many lines of outputs from gdb omitted)
Core was generated by `./LSystem'.
Program terminated with signal 11,
Segmentation fault.
'#0' 0x080e6433 in CLClient::connectToServer (this=0xf2afd898, conn=11) at liccomm/LClient.cpp:214
214 memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
gdb says the crash occurs at Line 214?
3. Frame information. (at Frame #0)
(gdb) info frame
Stack level 0, frame at 0xf2afd7e0:
eip = 0x80e6433 in CLClient::connectToServer (liccomm/LClient.cpp:214); saved eip 0x80e6701
called by frame at 0xf2afd820
source language c++.
Arglist at 0xf2afd7d8, args: this=0xf2afd898, conn=11
Locals at 0xf2afd7d8, Previous frame's sp is 0xf2afd7e0
Saved registers:
ebx at 0xf2afd7cc, ebp at 0xf2afd7d8, esi at 0xf2afd7d0, edi at 0xf2afd7d4, eip at 0xf2afd7dc
The frame is at f2afd7e0, why it's different than the rsp from Part 1, which is f2afd4e0? I guess the user may have provided me with mismatched core dump file (whose pid is 19009) and /var/log/messages file (which indicates a pid 4688).
4. The source
(gdb) list +
209
210 //pHost is declared as struct hostent* and 'pHost = gethostbyname(serverAddress);'
211 memset( &a4, 0, sizeof(a4) );
212 a4.sin_family = AF_INET;
213 a4.sin_port = htons( nPort );
214 memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
215
216 aalen = sizeof(a4);
217 aa = (struct sockaddr *)&a4;
I could not see anything wrong with Line 214. And this part of the code must ran many times during the runtime of 2 days.
5. The variables
Since gdb indicated that Line 214 was the culprit. I printed everything.
memcpy((char *) & (a4.sin_addr), pHost->h_addr, pHost->h_length);
(gdb) print a4.sin_addr
$1 = {s_addr = 0}
(gdb) print &(a4.sin_addr)
$2 = (in_addr *) 0xf2afd794
(gdb) print pHost->h_addr_list[0]
$3 = 0xa24af30 "\202}\204\250"
(gdb) print pHost->h_length
$4 = 4
(gdb) print memcpy
$5 = {} 0x2fcf90
So I basically printed everything that's at Line 214. ('pHost->h_addr_list[0]' is 'pHost->h_addr' due to '#define h_addr h_addr_list[0]')
I was not able to catch anything wrong. Did you catch anything fishy? Is it possible the memory has been corrupted somewhere else? I appreciate your help!
[edited] 6. back trace
(gdb) bt
'#0' 0x080e6433 in CLClient::connectToServer (this=0xf2afd898, conn=11) at liccomm/LClient.cpp:214
'#1' 0x080e6701 in CLClient::connectToLMServer (this=0xf2afd898) at liccomm/LClient.cpp:121
... (Frames 2~7 omitted, not relevant)
'#8' 0x080937f2 in handleConnectionStarter (par=0xf3563f98) at LManager.cpp:166
'#9' 0xf7f5fb41 in ?? ()
'#10' 0xf3563f98 in ?? ()
'#11' 0xf2aff31c in ?? ()
'#12' 0x00000000 in ?? ()
I followed the nested calls. They are correct.
The problem with the memcpy is that the source location is not of the same type than the destination.
You should use inet_addr to convert addresses from string to binary
a4.sin_addr = inet_addr(pHost->h_addr);
The previous code may not work depending on the implementation (some my return struct in_addr, others will return unsigned long, but the principle is the same.
I was writing an little board game which has to add and show an image on a button after clicking on it, and then calling back some other function to show an image on other buttons,but the program didn't run as I think,the widget didn't show until all those functions done.
Here is debug:
Breakpoint 1, GameControl::button_clicked (widget=0x80dad08, data=0x80563e0) at interface.cc:582
582 image = gtk_image_new_from_file ("arrow.bmp");
(gdb) step
583 gtk_container_add (GTK_CONTAINER (widget), image);
(gdb) step
584 gtk_widget_show (image);
(gdb) step
585 computer_move (widget, &control);
(gdb) step
GameControl::computer_move (widget=0x80dad08, data=0x80563e0) at interface.cc:520
520 computer_moving = true;
(gdb) break interface.cc:586
Breakpoint 2 at 0x804cdab: file interface.cc, line 586.
(gdb) continue
Continuing.
Breakpoint 2, GameControl::button_clicked (widget=0x80dad08, data=0x80563e0) at interface.cc:586
586 break;
(gdb) step
593 end_dialog ();
(gdb) next
595 }
(gdb) step
0xb7b1c243 in g_cclosure_marshal_VOID__VOIDv () from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
(gdb) step
Single stepping until exit from function g_cclosure_marshal_VOID__VOIDv,which has no line number information.
0xb7b33a29 in g_signal_emit_valist () from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
(gdb) next
Single stepping until exit from function g_signal_emit_valist,
which has no line number information.
0xb7b34453 in g_signal_emit () from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
(gdb) continue
Continuing.
[Thread 0xb6b86b40 (LWP 7820) exited]
[Thread 0xb61ffb40 (LWP 7821) exited]
[Inferior 1 (process 7817) exited normally]
until the last continue command was executed, the widget shows, for somehow the widget didn't show when it went to "gtk_widget_show ()" , any suggestions?
GTK+, like most GUI toolkits, is event-driven.
You are supposed to return from your callbacks so the main event loop (gtk_main()) can process the next event, otherwise the whole program just freezes.
If you want to process some events half-way through your callback, you do so explicitly. Straight from the docs:
/* computation going on */
while (gtk_events_pending ())
gtk_main_iteration ();
/* computation continued */
I was debugging my app with gdb.
I used break main
So it can break when main is called.
Know if I use thread info it shows that thread count is 1.
How a thread is starting before main ?
I don't have any thread call in my call so from where thread is getting created. I am using these libs
sqlite , curl , pcre , c-client
Update
I have written a sample program to test that if all program start with single thread
#include<iostream>
int main(int argc,char *argv[]){
std:: cout<<"Will I have any thread";
return 0;
}
but when I debug it with gdb
(gdb) break main
Breakpoint 1 at 0x400783: file threadtest.cpp, line 3.
(gdb) run
Starting program: /home/vivek/Desktop/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
3 std:: cout<<"Will I have any thread";
(gdb) info threads
* 1 process 21608 main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
(gdb)
it doesn't show the same information. It show 1 process not 1 thread.
When I compile it with -lpthread it show 1 thread.
So program start with one thread when we use lpthread ?
or GDB behaves like that ?
All programs have at least 1 thread, the main thread. The program is started before main since the C++ runtime does some initializing before main() starts, like calling all global objects which have constructors.
The operating system creates a process space with one thread and calls the application loader to execute the application in that thread, which in turns performs some initial setup (gathering command line arguments into argc and argv, for example) and calls main.
For the sample App when I compile it with -lpthread it shows 1 thread is running.
So lpthread is playing key point here.
(gdb) break main
Breakpoint 1 at 0x400793: file threadtest.cpp, line 3.
(gdb) run
Starting program: /home/vivek/Desktop/a.out
[Thread debugging using libthread_db enabled]
Breakpoint 1, main (argc=1, argv=0x7fffffffe728) at threadtest.cpp:3
3 std:: cout<<"Will I have any thread";
(gdb) info threads
* 1 Thread 0x2aaaaaac8bb0 (LWP 21649) main (argc=1, argv=0x7fffffffe728)
at threadtest.cpp:3
(gdb)