* Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
* Copyright (C) 2014 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 2 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: GPL-2.0-only
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <getopt.h>
#include <unistd.h>
#include <ctype.h>
#include <dirent.h>
-#include <byteswap.h>
+#include <common/compat/endian.h>
#include <inttypes.h>
#include <stdbool.h>
#include <version.h>
#include <lttng/lttng.h>
#include <common/common.h>
+#include <common/spawn-viewer.h>
#include <common/utils.h>
-#define DEFAULT_VIEWER "babeltrace"
-
#define COPY_BUFLEN 4096
#define RB_CRASH_DUMP_ABI_LEN 32
};
/* Variables */
-static char *progname,
- *opt_viewer_path = NULL,
- *opt_output_path = NULL;
+static const char *progname;
+static char *opt_viewer_path = NULL;
+static char *opt_output_path = NULL;
-static char *input_path;
+static char *the_input_path;
int lttng_opt_quiet, lttng_opt_verbose, lttng_opt_mi;
static void version(FILE *ofp)
{
fprintf(ofp, "%s (LTTng Crash Trace Viewer) " VERSION " - " VERSION_NAME
-"%s\n",
+ "%s%s\n",
progname,
- GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION);
+ GIT_VERSION[0] == '\0' ? "" : " - " GIT_VERSION,
+ EXTRA_VERSION_NAME[0] == '\0' ? "" : " - " EXTRA_VERSION_NAME);
}
/*
}
}
- if (!opt_viewer_path) {
- opt_viewer_path = DEFAULT_VIEWER;
- }
-
/* No leftovers, or more than one input path, print usage and quit */
if (argc - optind != 1) {
ERR("Command-line error: Specify exactly one input path");
goto error;
}
- input_path = argv[optind];
+ the_input_path = argv[optind];
end:
return ret;
switch (size) {
case 1: return *(uint8_t *) ptr;
case 2: if (layout->reverse_byte_order) {
- return __bswap_16(*(uint16_t *) ptr);
+ return bswap_16(*(uint16_t *) ptr);
} else {
return *(uint16_t *) ptr;
}
case 4: if (layout->reverse_byte_order) {
- return __bswap_32(*(uint32_t *) ptr);
+ return bswap_32(*(uint32_t *) ptr);
} else {
return *(uint32_t *) ptr;
}
case 8: if (layout->reverse_byte_order) {
- return __bswap_64(*(uint64_t *) ptr);
+ return bswap_64(*(uint64_t *) ptr);
} else {
return *(uint64_t *) ptr;
}
}
static
-int get_crash_layout(struct lttng_crash_layout *layout, int fd)
+int get_crash_layout(struct lttng_crash_layout *layout, int fd,
+ const char *input_file)
{
char *map;
int ret = 0, unmapret;
const struct crash_abi_unknown *abi;
uint16_t endian;
enum lttng_crash_type layout_type;
+ struct stat stat;
+ ret = fstat(fd, &stat);
+ if (ret < 0) {
+ PERROR("Failed to fstat '%s'", input_file);
+ return -1;
+ }
+ if (stat.st_size < RB_CRASH_DUMP_ABI_LEN) {
+ ERR("File '%s' truncated: file length of %" PRIi64
+ " bytes does not meet the minimal expected "
+ "length of %d bytes",
+ input_file, (int64_t) stat.st_size,
+ RB_CRASH_DUMP_ABI_LEN);
+ return -1;
+ }
map = mmap(NULL, RB_CRASH_DUMP_ABI_LEN, PROT_READ, MAP_PRIVATE,
fd, 0);
if (map == MAP_FAILED) {
subbuf_ptr + layout->offset.packet_size,
layout->length.packet_size);
if (layout->reverse_byte_order) {
- packet_size = __bswap_64(packet_size);
+ packet_size = bswap_64(packet_size);
}
packet_size /= CHAR_BIT;
} else {
*/
patch_size = committed * CHAR_BIT;
if (layout->reverse_byte_order) {
- patch_size = __bswap_64(patch_size);
+ patch_size = bswap_64(patch_size);
}
if (layout->length.content_size) {
memcpy(subbuf_ptr + layout->offset.content_size,
}
/* Query the crash ABI layout */
- ret = get_crash_layout(&layout, fd_src);
+ ret = get_crash_layout(&layout, fd_src, input_file);
if (ret) {
goto close_src;
}
if (!dir) {
PERROR("Cannot open '%s' path", path);
ret = -errno;
- goto end;
+ goto end_no_closedir;
}
path_len = strlen(path);
if (closeret) {
PERROR("closedir");
}
+end_no_closedir:
return ret;
}
static
-int view_trace(const char *viewer_path, const char *trace_path)
+int view_trace(const char *trace_path, char *viewer_path)
{
pid_t pid;
/* Child */
int ret;
- ret = execlp(viewer_path, viewer_path,
- trace_path, (char *) NULL);
+ ret = spawn_viewer(trace_path, viewer_path, false);
if (ret) {
- PERROR("execlp");
exit(EXIT_FAILURE);
}
- exit(EXIT_SUCCESS); /* Never reached */
+ /* Never reached */
+ exit(EXIT_SUCCESS);
}
return 0;
}
}
}
- ret = extract_trace_recursive(output_path, input_path);
+ ret = extract_trace_recursive(output_path, the_input_path);
if (ret < 0) {
has_warning = true;
goto end;
}
if (!opt_output_path) {
/* View trace */
- ret = view_trace(opt_viewer_path, output_path);
+ ret = view_trace(output_path, opt_viewer_path);
if (ret) {
has_warning = true;
}