aboutsummaryrefslogtreecommitdiff
path: root/libctf/ctf-archive.c
diff options
context:
space:
mode:
authorNick Alcock <nick.alcock@oracle.com>2024-07-15 19:55:40 +0100
committerNick Alcock <nick.alcock@oracle.com>2024-07-31 21:02:05 +0100
commit36c771b1794c43193a73201dcea51827f2ef8273 (patch)
tree896722b0c52dc4fa097b6a4474a9cd99486ea689 /libctf/ctf-archive.c
parent87b2f673102884d7c69144c85a26ed5dbaa4f86a (diff)
downloadgdb-36c771b1794c43193a73201dcea51827f2ef8273.zip
gdb-36c771b1794c43193a73201dcea51827f2ef8273.tar.gz
gdb-36c771b1794c43193a73201dcea51827f2ef8273.tar.bz2
libctf: fix CTF dict compression
Commit 483546ce4f3 ("libctf: make ctf_serialize() actually serialize") accidentally broke dict compression. There were two bugs: - ctf_arc_write_one_ctf was still making its own decision about whether to compress the dict via direct ctf_size comparison, which is unfortunate because now that it no longer calls ctf_serialize itself, ctf_size is always zero when it does this: it should let the writing functions decide on the threshold, which they contain code to do which is simply not used for lack of one trivial wrapper to write to an fd and also provide a compression threshold - ctf_write_mem, the function underlying all writing as of the commit above, was calling zlib's compressBound and avoiding compression if this returned a value larger than the input. Unfortunately compressBound does not do a trial compression and determine whether the result is compressible: it just adds zlib header sizes to the value passed in, so our test would *always* have concluded that the value was incompressible! Avoid by simply always compressing if the raw size is larger than the threshold: zlib is quite clever enough to avoid actually compressing if the data is incompressible. Add a testcase for this. libctf/ * ctf-impl.h (ctf_write_thresholded): New... * ctf-serialize.c (ctf_write_thresholded): ... defined here, a wrapper around... (ctf_write_mem): ... this. Don't check compressibility. (ctf_compress_write): Reimplement as a ctf_write_thresholded wrapper. (ctf_write): Likewise. * ctf-archive.c (arc_write_one_ctf): Just call ctf_write_thresholded rather than trying to work out whether to compress. * testsuite/libctf-writable/ctf-compressed.*: New test.
Diffstat (limited to 'libctf/ctf-archive.c')
-rw-r--r--libctf/ctf-archive.c8
1 files changed, 1 insertions, 7 deletions
diff --git a/libctf/ctf-archive.c b/libctf/ctf-archive.c
index c602705..0034bf0 100644
--- a/libctf/ctf-archive.c
+++ b/libctf/ctf-archive.c
@@ -265,16 +265,10 @@ arc_write_one_ctf (ctf_dict_t *f, int fd, size_t threshold)
uint64_t ctfsz = 0;
char *ctfszp;
size_t ctfsz_len;
- int (*writefn) (ctf_dict_t * fp, int fd);
if ((off = lseek (fd, 0, SEEK_CUR)) < 0)
return errno * -1;
- if (f->ctf_size > threshold)
- writefn = ctf_compress_write;
- else
- writefn = ctf_write;
-
/* This zero-write turns into the size in a moment. */
ctfsz_len = sizeof (ctfsz);
ctfszp = (char *) &ctfsz;
@@ -287,7 +281,7 @@ arc_write_one_ctf (ctf_dict_t *f, int fd, size_t threshold)
ctfszp += writelen;
}
- if (writefn (f, fd) != 0)
+ if (ctf_write_thresholded (f, fd, threshold) != 0)
return f->ctf_errno * -1;
if ((end_off = lseek (fd, 0, SEEK_CUR)) < 0)