When loading an executable onto a board using OpenOCD and GDB, I get something similar to (snippet taken from here):
$ arm-none-eabi-gdb example.elf
(gdb) target remote localhost:3333
Remote debugging using localhost:3333
...
(gdb) monitor reset halt
...
(gdb) load
Loading section .vectors, size 0x100 lma 0x20000000
Loading section .text, size 0x5a0 lma 0x20000100
Loading section .data, size 0x18 lma 0x200006a0
Start address 0x2000061c, load size 1720
Transfer rate: 22 KB/sec, 573 bytes/write.
(gdb) continue
Continuing.
...
What does lma mean in this context?
That means "Local Memory Address", which is the address in memory where code or data has been loaded to:
http://www.embeddedrelated.com/usenet/embedded/show/77071-1.php
Related
I am looking for a specific series of bytes in the memory of a program in GDB.
'find' starting above a certain address (0x104f90) works, but 'find' starting below that address does not:
(gdb) find /w 0x104f90, 0x108fe4, 0x6863203b
0x108e08
0x108e58
0x108ee8
vs
(gdb) find /w 0x104f80, 0x108fe4, 0x6863203b
Pattern not found.
The memory around this address is (seemingly) accessible by GDB:
(gdb) x/12x 0x104f80
0x104f80: 0x00000000 0x00000000 0x00000000 0x00000000
0x104f90: 0x00000000 0x00000000 0x00000000 0x00000000
0x104fa0: 0x00000000 0x00000000 0x00000000 0x00000000
And both of these addresses are on the heap -- info proc mappings says the heap runs from 0xe7000 - 0x109000
Can anyone advise on what I'm missing here? Thank you!
The problem was that I was using gdbserver, and there is a bug in gdbserver where the 'find' function gives up if it doesn't find what it's looking for in 16,000 bytes. See https://sourceware.org/pipermail/gdb-patches/2020-April/167829.html for the official bug report.
The solutions are either update to gdb 10 (which will have a fix), or limit 'find' queries to less than 16,000 bytes
My application randomly and rarely crashes with segmentation fault signal.
When coredump is opened in GDB following can be seen:
arm instruction leading to crash is:
0x7f8ea08130 fd 7b b7 a9 stp x29, x30, [sp,#-144]!
When code of crashed frame is browsed in GDB, breakpoint stops at opening curly brace of a function:
void SomeClass::someMethod(const std::string& s, int i)
>{
...
}
examining of 'sp' register gives following output:
x $sp
>~"0x7fc761a070:\t0xc761a270\n"
x $sp-144\n"
>~"0x7fc7619fe0:\t"
>&"Cannot access memory at address 0x7fc7619fe0\n"
>169^error,msg="Cannot access memory at address 0x7fc7619fe0"
stack trace seems fine and not corrupted
there are roughly 300 frames in stack and stack size limit is set to be 8192K
UPD: the pagesize in the system is 4k:
>grep -i pagesize /proc/1/smaps
KernelPageSize: 4 kB
MMUPageSize: 4 kB
What else I can check to debug this issue?
I use OpenOCD + GDB to debug the firmware. When I type load it loads the code to the FLASH memory:
Loading section ExtFlashSection, size 0x3fe000 lma 0x90000000
Loading section .isr_vector, size 0x1f8 lma 0x8000000
Loading section .text, size 0x19978 lma 0x8000200
Loading section .rodata, size 0x52d0 lma 0x8019b78
Loading section .ARM, size 0x8 lma 0x801ee48
Loading section .init_array, size 0x10 lma 0x801ee50
Loading section .fini_array, size 0x4 lma 0x801ee60
Loading section TextFlashSection, size 0x8 lma 0x801ee64
Loading section FontFlashSection, size 0x30b1c lma 0x801ee6c
Loading section .data, size 0x9c lma 0x804f988
Start address 0x80005f0, load size 4512284
Transfer rate: 89 KB/sec, 2926 bytes/write.
However, I want the ExtFlashSection to be not loaded, because I load it manually by external tool (it extracts the contents from the ELF and flashes). I tried adding NOLOAD attribute to that section, but then it is not present in the final ELF file (so I can not extract it).
How to tell GDB or OpenOCD to discard the contents of ExtFlashSection?
I set a watch point on memory location in gdb and load a application through gdb load command. watch point does not hit during load command although memory location is being changed during loading of application.
(gdb) watch *0x1c
Hardware watchpoint 2: *0x1c
(gdb) p/x *0x1c
$2 = 0xffffffff
(gdb) load
Loading section .text, size 0x53b4 lma 0x0
Loading section .eh_frame, size 0x4 lma 0x53b4
Loading section .ARM.exidx, size 0x8 lma 0x53b8
Loading section .rodata, size 0x238 lma 0x53c0
Loading section .data, size 0x520 lma 0x55f8
Start address 0xe4, load size 23320
Transfer rate: 9 KB/sec, 4664 bytes/write.
(gdb) p/x *0x1c
$3 = 0xfdfcdf08
(gdb)
Does watch point work during gdb load command?
I think it would be very unexpected if this triggered. Watchpoints are for changes made by running your program. In this case, your program isn't running, it is being loaded.
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.