diff --git a/src/PerfCounters.cc b/src/PerfCounters.cc index d567809389b..8ef181473e3 100644 --- a/src/PerfCounters.cc +++ b/src/PerfCounters.cc @@ -21,6 +21,7 @@ #include #endif #include +#include #include #include @@ -1243,6 +1244,19 @@ static struct perf_event_attr init_hw_breakpoint_attr() { attr.wakeup_events = 1; attr.precise_ip = 3; attr.disabled = 1; + +#if defined(__i386__) + struct utsname buf; + if (uname(&buf) != 0) { + FATAL() << "Failed to call uname"; + } + if (strcmp(buf.machine, "x86_64") == 0) { + /* A 32-bit rr running at a 64-bit kernel + * needs to set bp_len as needed by the kernel. */ + attr.bp_len = HW_BREAKPOINT_LEN_8; + } +#endif + return attr; } diff --git a/src/record_syscall.cc b/src/record_syscall.cc index ae6b86fe914..78e44ef152e 100644 --- a/src/record_syscall.cc +++ b/src/record_syscall.cc @@ -6375,7 +6375,7 @@ static void check_outside_mappings(const KernelMapping& tracee_km, const RecordS #if defined(__i386__) struct utsname buf; if (uname(&buf) != 0) { - FATAL() << "Failed to read /proc"; + FATAL() << "Failed to call uname"; } if (sizeof(void*) == 4 && strcmp(buf.machine, "x86_64") == 0) { /* Running 32-bit rr at a 64-bit kernel is not going to work because diff --git a/src/test/fd_leak.run b/src/test/fd_leak.run index a0a18db08d5..a54650a5b36 100644 --- a/src/test/fd_leak.run +++ b/src/test/fd_leak.run @@ -1,4 +1,7 @@ source `dirname $0`/util.sh + +skip_if_rr_32_bit_with_shell_64_bit + num_baseline=$(ls -la /proc/self/fd | wc -l) just_record $(which rr) "record --nested=detach ls -la /proc/self/fd" replay diff --git a/src/test/rlimit.c b/src/test/rlimit.c index 8d0a671092b..5555a13038b 100644 --- a/src/test/rlimit.c +++ b/src/test/rlimit.c @@ -2,6 +2,19 @@ #include "util.h" +int kernel_is_32bit_x86(void) +{ +#if defined(__i386__) + struct utsname buf; + if (uname(&buf) != 0) + return 0; + + if (strcmp(buf.machine, "i686") == 0) // running at a 32bit kernel + return 1; +#endif + return 0; +} + int main(void) { struct rlimit* r; struct rlimit* r2; @@ -14,6 +27,11 @@ int main(void) { test_assert(r->rlim_max > 0); VERIFY_GUARD(r); + /* When running a 32-bit kernel and using the 64-bit rlimit struct, + * a value above 0xfffffffe fails. */ + if (kernel_is_32bit_x86()) + r->rlim_cur &= 0xffffffff; + r->rlim_cur /= 2; test_assert(0 == setrlimit(RLIMIT_FSIZE, r)); VERIFY_GUARD(r); diff --git a/src/test/unmap_vdso.run b/src/test/unmap_vdso.run index 5946364557d..66b7a4ef1f2 100644 --- a/src/test/unmap_vdso.run +++ b/src/test/unmap_vdso.run @@ -1,4 +1,7 @@ source `dirname $0`/util.sh + +skip_if_rr_32_bit_with_shell_64_bit + RECORD_ARGS="--unmap-vdso" just_record cat /proc/self/maps if grep "vdso" record.out; then