void dump_hex(struct buffer *out, const char *pfx, const void *buf, int len, int unsafe);
int may_access(const void *ptr);
void *resolve_sym_name(struct buffer *buf, const char *pfx, void *addr);
+const char *get_exec_path();
#if defined(USE_BACKTRACE)
/* Note that this may result in opening libgcc() on first call, so it may need
/* bit values to go with "warned" above */
#define WARN_ANY 0x00000001 /* any warning was emitted */
#define WARN_FORCECLOSE_DEPRECATED 0x00000002
+#define WARN_EXEC_PATH 0x00000004 /* executable path already reported */
/* to be used with warned and WARN_* */
#include <common/initcall.h>
#include <common/standard.h>
#include <common/time.h>
+#include <common/version.h>
#include <types/cli.h>
#include <types/global.h>
va_list argp;
if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
+ if (!(warned & WARN_EXEC_PATH)) {
+ const char *path = get_exec_path();
+
+ warned |= WARN_EXEC_PATH;
+ ha_notice("haproxy version is %s\n", haproxy_version);
+ if (path)
+ ha_notice("path to executable is %s\n", path);
+ }
va_start(argp, fmt);
print_message("ALERT", fmt, argp);
va_end(argp);
#include <link.h>
#endif
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
+#include <sys/auxv.h>
+#endif
+
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
}
}
+/* Tries to report the executable path name on platforms supporting this. If
+ * not found or not possible, returns NULL.
+ */
+const char *get_exec_path()
+{
+ const char *ret = NULL;
+
+#if (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
+ long execfn = getauxval(AT_EXECFN);
+
+ if (execfn && execfn != ENOENT)
+ ret = (const char *)execfn;
+#endif
+ return ret;
+}
+
#ifdef __ELF__
/* calls dladdr() or dladdr1() on <addr> and <dli>. If dladdr1 is available,
* also returns the symbol size in <size>, otherwise returns 0 there.