diff --git a/i3-dump-log/main.c b/i3-dump-log/main.c index 30dd514f..6b500ea3 100644 --- a/i3-dump-log/main.c +++ b/i3-dump-log/main.c @@ -55,8 +55,35 @@ int main(int argc, char *argv[]) { } char *shmname = root_atom_contents("I3_SHMLOG_PATH"); - if (shmname == NULL) + if (shmname == NULL) { + /* Something failed. Let’s invest a little effort to find out what it + * is. This is hugely helpful for users who want to debug i3 but are + * not used to the procedure yet. */ + xcb_connection_t *conn; + int screen; + if ((conn = xcb_connect(NULL, &screen)) == NULL || + xcb_connection_has_error(conn)) { + fprintf(stderr, "i3-dump-log: ERROR: Cannot connect to X11.\n\n"); + if (getenv("DISPLAY") == NULL) { + fprintf(stderr, "Your DISPLAY environment variable is not set.\n"); + fprintf(stderr, "Are you running i3-dump-log via SSH or on a virtual console?\n"); + fprintf(stderr, "Try DISPLAY=:0 i3-dump-log\n"); + exit(1); + } + fprintf(stderr, "FYI: The DISPLAY environment variable is set to \"%s\".\n", getenv("DISPLAY")); + exit(1); + } + if (root_atom_contents("I3_CONFIG_PATH") != NULL) { + fprintf(stderr, "i3-dump-log: ERROR: i3 is running, but SHM logging is not enabled.\n\n"); + if (!is_debug_build()) { + fprintf(stderr, "You seem to be using a release version of i3:\n %s\n\n", I3_VERSION); + fprintf(stderr, "Release versions do not use SHM logging by default,\ntherefore i3-dump-log does not work.\n\n"); + fprintf(stderr, "Please follow this guide instead:\nhttp://i3wm.org/docs/debugging-release-version.html\n"); + exit(1); + } + } errx(EXIT_FAILURE, "Cannot get I3_SHMLOG_PATH atom contents. Is i3 running on this display?"); + } if (*shmname == '\0') errx(EXIT_FAILURE, "Cannot dump log: SHM logging is disabled in i3."); diff --git a/include/libi3.h b/include/libi3.h index b88bcb67..2126e100 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -242,4 +242,11 @@ void draw_text(char *text, size_t text_len, bool is_ucs2, xcb_drawable_t drawabl */ int predict_text_width(char *text, size_t text_len, bool is_ucs2); +/** + * Returns true if this version of i3 is a debug build (anything which is not a + * release version), based on the git version number. + * + */ +bool is_debug_build() __attribute__((const)); + #endif diff --git a/libi3/is_debug_build.c b/libi3/is_debug_build.c new file mode 100644 index 00000000..3173c122 --- /dev/null +++ b/libi3/is_debug_build.c @@ -0,0 +1,17 @@ +#include +#include + +/* + * Returns true if this version of i3 is a debug build (anything which is not a + * release version), based on the git version number. + * + */ +bool is_debug_build() { + /* i3_version contains either something like this: + * "4.0.2 (2011-11-11, branch "release")". + * or: "4.0.2-123-gCOFFEEBABE (2011-11-11, branch "next")". + * + * So we check for the offset of the first opening round bracket to + * determine whether this is a git version or a release version. */ + return ((strchr(I3_VERSION, '(') - I3_VERSION) > 10); +} diff --git a/src/main.c b/src/main.c index 14786d29..44c3f3cb 100644 --- a/src/main.c +++ b/src/main.c @@ -25,9 +25,6 @@ * RLIM_INFINITY for i3 debugging versions. */ struct rlimit original_rlimit_core; -/* Whether this version of i3 is a debug build or a release build. */ -bool debug_build = false; - /** The number of file descriptors passed via socket activation. */ int listen_fds; @@ -246,7 +243,7 @@ static void handle_signal(int sig, siginfo_t *info, void *data) { int main(int argc, char *argv[]) { /* Keep a symbol pointing to the I3_VERSION string constant so that we have * it in gdb backtraces. */ - const char *i3_version = I3_VERSION; + const char *i3_version __attribute__ ((unused)) = I3_VERSION; char *override_configpath = NULL; bool autostart = true; char *layout_path = NULL; @@ -291,16 +288,8 @@ int main(int argc, char *argv[]) { * (file) logging. */ init_logging(); - /* i3_version contains either something like this: - * "4.0.2 (2011-11-11, branch "release")". - * or: "4.0.2-123-gCOFFEEBABE (2011-11-11, branch "next")". - * - * So we check for the offset of the first opening round bracket to - * determine whether this is a git version or a release version. */ - debug_build = ((strchr(i3_version, '(') - i3_version) > 10); - /* On non-release builds, disable SHM logging by default. */ - shmlog_size = (debug_build ? 25 * 1024 * 1024 : 0); + shmlog_size = (is_debug_build() ? 25 * 1024 * 1024 : 0); start_argv = argv; @@ -475,7 +464,7 @@ int main(int argc, char *argv[]) { init_logging(); /* Try to enable core dumps by default when running a debug build */ - if (debug_build) { + if (is_debug_build()) { struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY }; setrlimit(RLIMIT_CORE, &limit);