diff --git a/clients/drcachesim/common/gzip_istream.h b/clients/drcachesim/common/gzip_istream.h new file mode 100644 index 00000000000..15a35bcef46 --- /dev/null +++ b/clients/drcachesim/common/gzip_istream.h @@ -0,0 +1,114 @@ +/* ********************************************************** + * Copyright (c) 2018-2020 Google, Inc. All rights reserved. + * **********************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of Google, Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* gzip_istream_t: a wrapper around zlib gzFile to match the parts of the + * std::istream interface we use for raw2trace and file_reader_t. + * Supports only limited seeking within the current internal buffer. + */ + +#ifndef _GZIP_ISTREAM_H_ +#define _GZIP_ISTREAM_H_ 1 + +#ifndef HAS_ZLIB +# error HAS_ZLIB is required +#endif +#include +#include + +/* We need to override the stream buffer class which is where the file + * reads happen. The stream buffer base class reads from eback()..egptr() + * with the next to read at gptr(). + */ +class gzip_istreambuf_t : public std::basic_streambuf> { +public: + gzip_istreambuf_t(const std::string &path) + { + file_ = gzopen(path.c_str(), "rb"); + if (file_ != nullptr) { + buf_ = new char[buffer_size_]; + } + } + ~gzip_istreambuf_t() override + { + delete[] buf_; + if (file_ != nullptr) + gzclose(file_); + } + int + underflow() override + { + if (file_ == nullptr) + return traits_type::eof(); + if (gptr() == egptr()) { + int len = gzread(file_, buf_, buffer_size_); + if (len <= 0) + return traits_type::eof(); + setg(buf_, buf_, buf_ + len); + } + return *gptr(); + } + std::iostream::pos_type + seekoff(std::iostream::off_type off, std::ios_base::seekdir dir, + std::ios_base::openmode which = std::ios_base::in) override + { + if (dir == std::ios_base::cur && + ((off >= 0 && gptr() + off < egptr()) || + (off < 0 && gptr() + off >= eback()))) + gbump(off); + else { + // Unsupported! + return -1; + } + return gptr() - eback(); + } + +private: + static const int buffer_size_ = 4096; + gzFile file_ = nullptr; + char *buf_ = nullptr; +}; + +class gzip_istream_t : public std::istream { +public: + explicit gzip_istream_t(const std::string &path) + : std::istream(new gzip_istreambuf_t(path)) + { + if (!rdbuf()) + setstate(std::ios::badbit); + } + virtual ~gzip_istream_t() override + { + delete rdbuf(); + } +}; + +#endif /* _GZIP_ISTREAM_H_ */ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw deleted file mode 100644 index 7cb0a613e9e..00000000000 Binary files a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw and /dev/null differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw.gz b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw.gz new file mode 100644 index 00000000000..82a2e68059b Binary files /dev/null and b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44811.2612.raw.gz differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw deleted file mode 100644 index 5234720a30a..00000000000 Binary files a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw and /dev/null differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw.gz b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw.gz new file mode 100644 index 00000000000..5ec45eb6124 Binary files /dev/null and b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44812.0713.raw.gz differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw deleted file mode 100644 index fc891345d9e..00000000000 Binary files a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw and /dev/null differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw.gz b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw.gz new file mode 100644 index 00000000000..d75f58ef8f5 Binary files /dev/null and b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44813.3661.raw.gz differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw deleted file mode 100644 index fbb09bb93c9..00000000000 Binary files a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw and /dev/null differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw.gz b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw.gz new file mode 100644 index 00000000000..1326ca685a1 Binary files /dev/null and b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44814.4595.raw.gz differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw deleted file mode 100644 index 88f1b2561e9..00000000000 Binary files a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw and /dev/null differ diff --git a/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw.gz b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw.gz new file mode 100644 index 00000000000..590831b0d49 Binary files /dev/null and b/clients/drcachesim/tests/drmemtrace.threadsig.aarch64.raw/raw/drmemtrace.threadsig.44815.2323.raw.gz differ diff --git a/clients/drcachesim/tests/offline-altbindir.templatex b/clients/drcachesim/tests/offline-altbindir.templatex index e8cb9238538..1b7a04a830e 100644 --- a/clients/drcachesim/tests/offline-altbindir.templatex +++ b/clients/drcachesim/tests/offline-altbindir.templatex @@ -5,7 +5,7 @@ Opcode mix tool results: 15165 : stp .* #elif defined(X86) && defined(X64) -ERROR: failed to initialize analyzer: Directory setup failed: Failed sanity checks for thread log file .*/drmemtrace.threadsig.aarch64/raw/drmemtrace.threadsig..*.raw: Architecture mismatch: trace recorded on aarch64 but tools built for x86_64 +ERROR: failed to initialize analyzer: Directory setup failed: Failed sanity checks for thread log file .*/drmemtrace.threadsig.aarch64/raw/drmemtrace.threadsig..*.raw.gz: Architecture mismatch: trace recorded on aarch64 but tools built for x86_64 #else ERROR: failed to initialize analyzer: Failed to create analysis tool: Tool failed to initialize: Failed to load binaries: Failed to map module /tmp/nonexistent/threadsig #endif diff --git a/clients/drcachesim/tracer/raw2trace.h b/clients/drcachesim/tracer/raw2trace.h index 8d0e6f255c1..4e4b2f81d96 100644 --- a/clients/drcachesim/tracer/raw2trace.h +++ b/clients/drcachesim/tracer/raw2trace.h @@ -61,6 +61,9 @@ #endif #define OUTFILE_SUFFIX "raw" +#ifdef HAS_ZLIB +# define OUTFILE_SUFFIX_GZ "gz" +#endif #define OUTFILE_SUBDIR "raw" #define TRACE_SUBDIR "trace" #ifdef HAS_ZLIB diff --git a/clients/drcachesim/tracer/raw2trace_directory.cpp b/clients/drcachesim/tracer/raw2trace_directory.cpp index 218290632d7..44267d7b295 100644 --- a/clients/drcachesim/tracer/raw2trace_directory.cpp +++ b/clients/drcachesim/tracer/raw2trace_directory.cpp @@ -49,6 +49,7 @@ # include #endif #ifdef HAS_ZLIB +# include "common/gzip_istream.h" # include "common/gzip_ostream.h" #endif @@ -108,9 +109,20 @@ raw2trace_directory_t::open_thread_log_file(const char *basename) strcmp(basename, DRMEMTRACE_FUNCTION_LIST_FILENAME) == 0) return ""; // Skip any non-.raw in case someone put some other file in there. - const char *basename_pre_suffix = strrchr(basename, '.'); - if (basename_pre_suffix != nullptr) - basename_pre_suffix = strstr(basename_pre_suffix, OUTFILE_SUFFIX); + const char *basename_dot = strrchr(basename, '.'); + if (basename_dot == nullptr) + return ""; + const char *basename_pre_suffix = nullptr; + bool is_gzipped = false; +#ifdef HAS_ZLIB + basename_pre_suffix = strstr(basename_dot, OUTFILE_SUFFIX_GZ); + if (basename_pre_suffix != nullptr) { + is_gzipped = true; + basename_dot = strrchr(basename_pre_suffix, '.'); + } +#endif + if (basename_pre_suffix == nullptr) + basename_pre_suffix = strstr(basename_dot, OUTFILE_SUFFIX); if (basename_pre_suffix == nullptr) return ""; if (dr_snprintf(path, BUFFER_SIZE_ELEMENTS(path), "%s%s%s", indir_.c_str(), DIRSEP, @@ -118,7 +130,14 @@ raw2trace_directory_t::open_thread_log_file(const char *basename) return "Failed to get full path of file " + std::string(basename); } NULL_TERMINATE_BUFFER(path); - in_files_.push_back(new std::ifstream(path, std::ifstream::binary)); + std::istream *ifile; +#ifdef HAS_ZLIB + if (is_gzipped) + ifile = new gzip_istream_t(path); +#endif + if (!is_gzipped) + ifile = new std::ifstream(path, std::ifstream::binary); + in_files_.push_back(ifile); if (!(*in_files_.back())) return "Failed to open thread log file " + std::string(path); std::string error = raw2trace_t::check_thread_file(in_files_.back()); diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index f0af34cf926..b7997ff397c 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -3348,7 +3348,8 @@ endif () # Test postprocessing and analysis with an alternate binary directory. # Limited to UNIX because the checked-in modules.log is in UNIX format # (Windows needs extra fields per library). - if (UNIX) + # Limited to ZLIB_FOUND because we test gzipped .raw files here as well. + if (UNIX AND ZLIB_FOUND) # We make a writable copy so we can both write the final trace there and run our # analyzer in a single command line. set(srcdir