How to calculate expected core file size - c++

How can I calculate the expected size of a coredump?
I have a truncated core file(coredump) from arm64 target. And I can find expected size of a core file(coredump), from output of gdb-multiarch.
BFD: warning: /home/.../core-m is truncated: expected core file size >= 748728320, found: 518127616
From above, I can find expected size of a coredump is 748728320 and its actual size is 518127616.
Now, I wonder how gdb-multiarch calculates the expected size of a coredump.
I can find size of each section, using readelf -e and I thought the sum of each section's size will be same with expected size of a core file. So I get the sum, but it is not equal to expected size of the coredump.
the sum: 748680864
expected size by `gdb-multiarch`: 748728320
How can I calculate this, correctly?
UPDATE
I've just got to know I can find the expected size of a coredump, from output of readelf -e. readelf -e shows offset and size of each segment. I got the result from my truncated coredump.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
NOTE 0x000000000000b2f8 0x0000000000000000 0x0000000000000000
0x000000000002b6a0 0x0000000000000000 0x0
LOAD 0x0000000000037000 0x000000556af44000 0x0000000000000000
0x0000000000001000 0x00000000008cc000 R E 0x1000
...
LOAD 0x000000002c831000 0x0000007fca9c5000 0x0000000000000000
0x00000000001da000 0x00000000001da000 RW 0x1000
From above, I can find offset and size of last segment. Offset is 0x2c831000, and size if 0x1da000. And expected size of dump will be 0x2c831000 + 0x1da000 = 0x2CA0B000(748728320). This is same with one from gdb-multiarch.
This approach can be used only if readelf is available. And I can't explain how the expected size of dump is calculated, still. I hope someone give me the explanation.

I use the following script, seems to work quite well. As the comment explains, we simply find the largest LOAD section end offset in the file. (Note that it accounts for sparse files.)
If I remember correctly, I lifted the technique from GDB's corefile loading code (or some similar standard tool that warns about corefile truncation).
#!/bin/bash
trap 'exit 1' ERR # Abort script on error.
if [[ $# != 1 ]] ; then
echo "$( basename $0 ) <coreFile>"
exit 1
fi
coreFile=$1
# Examine all LOAD sections in the corefile, calculate the file offset of each section's end,
# and find the largest offset.
expectedSize=$( readelf -l ${coreFile} | grep -A 1 LOAD |
while read type offset etc && read fsize etc ; do
echo $(( $offset + $fsize ))
done | sort -n | tail -n 1 )
actualSize=$( du --block-size=1 --apparent-size ${coreFile} | cut -f1 )
physicalSize=$( du --block-size=1 ${coreFile} | cut -f1 )
if [[ ${actualSize} < ${expectedSize} ]] ; then
echo "Physical size ${physicalSize}"
echo "Expected logical size ${expectedSize}"
echo "Actual logical size ${actualSize}"
exit 2
fi

Related

GDB improperly tokenizes command-line arguments containing spaces

(This is possibly related to Pass arguments with space in GDB?, which did not get resolved.)
Witness the following:
zlaski#RUMCAJS /cygdrive/d/music/wurlitzer/Drum And Bass
$ ls Wen\ -\ Commotion.backup.mp3
'Wen - Commotion.backup.mp3'
zlaski#RUMCAJS /cygdrive/d/music/wurlitzer/Drum And Bass
$ gdb -q -ex start --args ls Wen\ -\ Commotion.backup.mp3
Reading symbols from ls...
Reading symbols from /usr/bin/ls.exe.dbg...
Temporary breakpoint 1 at 0x1004181e0: file /usr/src/debug/coreutils-9.0-1/src/ls.c, line 1658.
Starting program: /usr/bin/ls Wen\ -\ Commotion.backup.mp3
[New Thread 34524.0x4edc]
[New Thread 34524.0x2abc]
[New Thread 34524.0x7dd4]
[New Thread 34524.0x7aa0]
Thread 1 "ls" hit Temporary breakpoint 1, main (argc=4, argv=0x7ffffcc20) at /usr/src/debug/coreutils-9.0-1/src/ls.c:1658
We are passing a single argument, Wen\ -\ Commotion.backup.mp3, to the ls program. However, gdb chops it into 3 pieces, which is why we wind up with an argc of 4 instead of 2:
(gdb) print argv[0]
$1 = 0xa00003380 "/usr/bin/ls"
(gdb) print argv[1]
$2 = 0x7ffffcc67 "Wen\\"
(gdb) print argv[2]
$3 = 0x7ffffcc6c "-\\"
(gdb) print argv[3]
$4 = 0x7ffffcc6f "Commotion.backup.mp3"
I have also tried the following incantations of the argument:
'Wen - Commotion.backup.mp3'
"Wen - Commotion.backup.mp3"
Wen\\ -\\ Commotion.backup.mp3
"Wen\\ -\\ Commotion.backup.mp3"
'Wen\\ -\\ Commotion.backup.mp3'
'Wen\ -\ Commotion.backup.mp3'
"Wen\ -\ Commotion.backup.mp3"
In all cases, the argument is chopped into 3 pieces.
I have an eerie feeling that I must be doing something wrong as it seems implausible that gdb would have such a glaring defect for all these years. Anyhoo, I hope that you gentlefolk can enlighten me here.
My configuration is as follows:
MACHTYPE=x86_64-unknown-cygwin
bash-4.4.12-3
coreutils-9.0-1
cygwin-3.4.3-1
gdb-11.2-1
Thanks!

Use of image magick compare command - how to catch the integer result of different pixels?

I am using this command line
compare -metric AE -fuzz 5% $OLD_JPG_ProcessFILE $JPG_ProcessFILE /tmp/JPG_PathFullFillName.gif
The command does work and throws me the result as an integer number of different pixels into the next command line of Putty - but I can't assign this integer value to a bash variable ...!
How to do that?
This command
var=$(compare -metric AE -fuzz 5% $OLD_JPG_ProcessFILE $JPG_ProcessFILE /tmp/JPG_PathFullFillName.gif)
does not work, $var remains empty ...!
Thanks in advance and BR
Testing around I have found the answer by appending "null: 2>&1" :
Pixel_Difference=$(compare -metric AE -fuzz 5% $OLD_JPG_ProcessFILE $JPG_ProcessFILE /tmp/JPG_PathFullFillName.gif null: 2>&1)
Works fine!
But why - what is the "magic" behind with "null: 2>&1" ???

gdb - finding the values of strncmp() function

I have a code which has hit a seg fault with strncmp() and I have this info below:
#7 0x00007f3662e5d4e7 in __strncmp_sse42 () from /lib64/libc.so.6
(gdb) info locals
No symbol table info available.
(gdb) info args
No symbol table info available.
(gdb) info frame
Stack level 7, frame at 0x7f35f4413b70:
rip = 0x7f3662e5d4e7 in __strncmp_sse42; saved rip = 0x7f35f64f5d6d
called by frame at 0x7f35f4413cc0, caller of frame at 0x7f35f4413b68
Arglist at 0x7f35f4413b60, args:
Locals at 0x7f35f4413b60, Previous frame's sp is 0x7f35f4413b70
Saved registers:
rip at 0x7f35f4413b68
Is there a way to check the args passed into this function? Any explanation will help me relate what is going on.
Appreciate the help in advance.
One way to trace args passed into system calls is to use ltrace. Not always guaranteed to be helpful, but quick and painless to try. Here's example of using ltrace to trace the calls made by particular invocation of grep command:
$ ltrace -s 200 grep XYZ hello.cc 2>&1 | grep XYZ
memcpy(0xe7f030, "XYZ\0", 4) = 0xe7f030
memchr("XYZ", '\n', 3) = nil
memcpy(0xe7f6b0, "XYZ", 3) = 0xe7f6b0
strlen("XYZ") = 3
strncmp("Y", "XYZ", 3) = 1
strncmp("XYZ", "Y", 1) = -1
strlen("XYZ") = 3
strcmp("XYZ", "XYZ") = 0
strlen("XYZ") = 3
memcpy(0xe7f630, "XYZ\0", 4) = 0xe7f630
strlen("XYZ") = 3
memcpy(0xe7f840, "XYZ", 3) = 0xe7f840
You're not specifying which operating system you're using, but try installing debug symbols for libc. E.g. libc6-dbg on Ubuntu/Debian.

Grabbing variable text under fixed heading

I have a log file like the sample below:
Pool id 1000c2
signal sizes 8
sig_conf 63 127 255 511 1663 4095 9247 65535
sig_alloc 214 8 38 1 4 0 0 0
stack sizes 8
stk_conf 256 512 1024 2048 4096 8192 16384 65536
stk_alloc 0 0 0 8 6 10 6 0
fragment info
fragment baseaddr lastaddr size sigsize stksize unused watermark_used%
0 018ae000 01d72b40 5000000 651680 245760 4102560 17
Current Pool Usage Info
Total_Pool_Size Current_Used_Pool Current_Used_Pool%
5000000 252535 5
blocks
30111a 2010f0 29010d0 6000c0
$
I need the value under the heading "Current_Used_Pool%". There are a number of such logs and the values are varying but the heading remains constant.
I tried to use awk but have failed so far. Please help.
Another approach:
awk '/Current_Used_Pool%/{N=NR+1;next} NR==N{print $3}'
The common, idiomatic awk approach is to just set/test a flag:
awk 'f{print $3;f=0} /Current_Used_Pool%/{f=1}'
See https://stackoverflow.com/a/18409469/1745001 for more examples of how to print records relative to some other record.
#slyclam I see under a different answer you wrote got syntax error awk: syntax error near line 1 awk: illegal statement near line 1 - that error message means you are using old, broken awk (/bin/awk on Solaris). Never use that awk is it is, well, old and broken. On Solaris use /usr/xpg4/bin/awk or, slightly inferior, nawk.
You can use this awk command to search for the value under a fixed column heading:
awk -v col="Current_Used_Pool%" '$0 ~ col {
for(i=1; i<=NF; i++)
if ($i == col) {
c=i
n=NR+1
break
}
} NR==n {
print $c
exit
}' file
Output:
5

How do I print only the value of a variable in GDB?

I have this script of GDB commands:
$ cat gdb_commands.txt
set pagination off
set logging file output.txt
set logging on
file stuff
b *0x80000014
run
echo ***DIFF THIS***\n
echo eax:
print $eax
echo ebx:
print $ebx
echo ecx:
print $ecx
echo edx:
print $edx
echo ***DIFF THIS END***\n
quit
If I run it in GDB I get this:
$ gdb -q -x gdb_commands.txt
Breakpoint 1 at 0x80000014
Breakpoint 1, 0x80000014 in _start ()
***DIFF THIS***
eax:$1 = 1
ebx:$2 = 2
ecx:$3 = 3
edx:$4 = 4
***DIFF THIS END***
A debugging session is active.
Inferior 1 [process 8947] will be killed.
Quit anyway? (y or n) [answered Y; input not from terminal]
So there is that ugly dollar sign thing. I can sed it out, but I would like to have GDB to do that. Is it possible?
(The reason I'm use GDB like this is because we are writing an emulator and want to test if it behaves correctly.)
ugly dollar sign thing ... I would like to have gdb to do that
You can control GDB's output precisely with printf command:
(gdb) print/x $rax
$1 = 0x7ffff7ffe2a0
(gdb) printf "0x%lx\n", $rax
0x7ffff7ffe2a0
There is a command that does exactly that:
(gdb) help output
Like "print" but don't put in value history and don't print newline.
This is useful in user-defined commands.
output prints the variables without the $1 = and the newline.