Skip to content

Commit 16782e8

Browse files
palveslancesix
authored andcommitted
gdb.rocm/runtime-core: Fix sparseness check
When running the gdb.rocm/runtime-core test on an NFS mounted directory, gdb.rocm/runtime-core.exp is incorrectly identifying the core dump as not sparse, even if coremerge did everything properly and the core dump is indeed sparse. The problem is that the code that tries to detect sparseness is incorrect. It assumes that stat.st_blocks is counted in stat.st_blksize units. This is incorrect. There is no correlation between st_blocks and st_blksize. st_blksize is instead the "preferred" block size for efficient filesystem I/O. Unfortunately, there is no portable way to get at the st_blocks unit byte size in TCL. Thus this commit switches from TCL `file stat` to invoking `du` (disk usage tool). You can find more details in new comments in the code. Co-Authored-By: Shahab Vahedi <[email protected]> Bug: SWDEV-485267 Change-Id: I63355b87bfbc31f9283f9f3a2461171371f7641a (cherry picked from commit c886465)
1 parent 3f6fe70 commit 16782e8

File tree

2 files changed

+66
-5
lines changed

2 files changed

+66
-5
lines changed

gdb/testsuite/gdb.rocm/runtime-core.exp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ proc do_test { fault } {
4545
return
4646
}
4747

48-
# Check that we obtained a sparse file.
49-
file stat $coredump corestat
50-
gdb_assert \
51-
{$corestat(size) > $corestat(blksize) * $corestat(blocks)} \
52-
"core is sparse"
48+
check_sparse $coredump "core is sparse"
5349

5450
remote_exec build "mv $coredump $coredump-$fault"
5551

gdb/testsuite/lib/gdb.exp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6672,6 +6672,71 @@ proc gdb_core_cmd { core test } {
66726672
return -1
66736673
}
66746674

6675+
# Figure out whether FILE is sparse. Returns 1 if FILE is sparse, 0
6676+
# if FILE is not sparse, and -1 if something went wrong. If MESSAGE
6677+
# is not empty, then issue PASS/FAIL/UNTESTED accordingly.
6678+
proc check_sparse { file {message ""} } {
6679+
# There is no portable way to check for sparseness with TCL.
6680+
#
6681+
# The standard test is to use the stat syscall to get the number
6682+
# of blocks in the file, multiply by the block size, and compare
6683+
# the result with the file's logical size. If smaller, then the
6684+
# file is sparse.
6685+
#
6686+
# We can get the file's logical size with TCL's "file size". We
6687+
# can use TCL "file stat" to find the number of file blocks in the
6688+
# "blocks" element of the returned array (same as stat.st_blocks
6689+
# in C). But we don't know what is the byte size of the blocks
6690+
# reported. It is NOT what "file stat" returns in the "blksize"
6691+
# array element (as same stat.st_blksize in C). As described at:
6692+
# https://pubs.opengroup.org/onlinepubs/007904875/basedefs/sys/stat.h.html
6693+
#
6694+
# "The unit for the st_blocks member of the stat structure is not
6695+
# defined within IEEE Std 1003.1-2001. In some implementations it
6696+
# is 512 bytes. It may differ on a file system basis. There is no
6697+
# correlation between values of the st_blocks and st_blksize, and
6698+
# the f_bsize (from <sys/statvfs.h>) structure members.
6699+
#
6700+
# Traditionally, some implementations defined the multiplier for
6701+
# st_blocks in <sys/param.h> as the symbol DEV_BSIZE."
6702+
#
6703+
# We could try to address this by writing our own little C program
6704+
# that tries to use the correct block size for the system.
6705+
# Looking at the `GNU du`'s source code, though, we see that not
6706+
# all systems have DEV_BSIZE (or S_BLKSIZE, which is similar), and
6707+
# then there are some systems that don't have any such macro and
6708+
# use 1024 as block size. So not even a 512 fallback works
6709+
# everywhere.
6710+
#
6711+
# It seems pointless to have to worry about portability like that
6712+
# when `du` exists and is installed (or easy to install) on
6713+
# practically every Unix-like system we might care about.
6714+
#
6715+
# Now, `du`'s behavior has a similar portability issue. While
6716+
# most `du` implementations report blocks in 512 bytes units, that
6717+
# is not guaranteed. Thankfully, "du -k" is in POSIX, which forces
6718+
# block size of 1024 bytes. So that's what we use.
6719+
set du_result [remote_exec host "du" [list "-k" "$file"]]
6720+
set du_status [lindex $du_result 0]
6721+
set du_output [lindex $du_result 1]
6722+
if {$du_status != 0} {
6723+
verbose -log "du failed with error code $du_status"
6724+
verbose -log "du output is: $du_output"
6725+
if {$message != ""} {
6726+
untested $message
6727+
}
6728+
return -1
6729+
}
6730+
# Get '123' from a string like "123 /path/to/file".
6731+
set blks [lindex [split $du_output] 0]
6732+
set size_on_disk [expr {1024 * $blks}]
6733+
set res [expr {$size_on_disk < [file size $file]}]
6734+
if {$message != ""} {
6735+
gdb_assert $res $message
6736+
}
6737+
return res
6738+
}
6739+
66756740
# Return the filename to download to the target and load on the target
66766741
# for this shared library. Normally just LIBNAME, unless shared libraries
66776742
# for this target have separate link and load images.

0 commit comments

Comments
 (0)