Diff
Modified: trunk/Source/bmalloc/ChangeLog (294213 => 294214)
--- trunk/Source/bmalloc/ChangeLog 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/ChangeLog 2022-05-15 02:08:04 UTC (rev 294214)
@@ -1,3 +1,35 @@
+2022-05-14 Justin Michaud <justin_mich...@apple.com>
+
+ [LIBPAS] Add extra assert information to malloc enumeration API
+ https://bugs.webkit.org/show_bug.cgi?id=240292
+
+ Reviewed by Yusuke Suzuki.
+
+ In the heap enumerator (which is a slow path), we have asserts that
+ have the opportunity to include extra information to aid debugging.
+
+ We add PAS_ASSERT_WITH_DETAIL, which stuffs extra data into registers before crashing
+ so that we can see it in crash logs. We also add a debugging option to allow logging
+ to syslog, for cases when we do not have access to stdout.
+
+ * libpas/src/libpas/pas_enumerate_segregated_heaps.c:
+ (consider_allocator):
+ * libpas/src/libpas/pas_local_allocator_config_kind.h:
+ (pas_local_allocator_config_kind_create_normal):
+ (pas_local_allocator_config_kind_create_primordial_partial):
+ (pas_local_allocator_config_kind_create_bitfit):
+ (pas_local_allocator_config_kind_get_segregated_page_config_kind):
+ (pas_local_allocator_config_kind_get_bitfit_page_config_kind):
+ (pas_local_allocator_config_kind_get_string):
+ * libpas/src/libpas/pas_log.c:
+ (pas_vlog):
+ * libpas/src/libpas/pas_utils.c:
+ (pas_crash_with_info_impl):
+ (pas_panic):
+ (pas_assertion_failed_no_inline):
+ (pas_assertion_failed_no_inline_with_extra_detail):
+ * libpas/src/libpas/pas_utils.h:
+
2022-05-07 Mark Lam <mark....@apple.com>
Force PAS_ASSERT to generate different crash sites for each assertion.
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_enumerate_segregated_heaps.c (294213 => 294214)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_enumerate_segregated_heaps.c 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_enumerate_segregated_heaps.c 2022-05-15 02:08:04 UTC (rev 294214)
@@ -603,7 +603,7 @@
if (verbose)
pas_log("Have allocator %p in page_ish = %p\n", allocator, (void*)allocator->page_ish);
- PAS_ASSERT_WITH_DETAIL(!pas_local_allocator_config_kind_is_bitfit(allocator->config_kind));
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!pas_local_allocator_config_kind_is_bitfit(allocator->config_kind), allocator->config_kind);
page_config = pas_segregated_page_config_kind_get_config(
pas_local_allocator_config_kind_get_segregated_page_config_kind(allocator->config_kind));
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_config_kind.h (294213 => 294214)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_config_kind.h 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_config_kind.h 2022-05-15 02:08:04 UTC (rev 294214)
@@ -86,7 +86,7 @@
#include "pas_segregated_page_config_kind.def"
#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
}
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return (pas_local_allocator_config_kind)0;
}
@@ -100,7 +100,7 @@
#include "pas_segregated_page_config_kind.def"
#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
}
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return (pas_local_allocator_config_kind)0;
}
@@ -114,7 +114,7 @@
#include "pas_bitfit_page_config_kind.def"
#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
}
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return (pas_local_allocator_config_kind)0;
}
@@ -129,7 +129,7 @@
#include "pas_segregated_page_config_kind.def"
#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
default:
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return (pas_segregated_page_config_kind)0;
}
}
@@ -144,7 +144,7 @@
#include "pas_bitfit_page_config_kind.def"
#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
default:
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return (pas_bitfit_page_config_kind)0;
}
}
@@ -170,7 +170,7 @@
#include "pas_bitfit_page_config_kind.def"
#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
}
- PAS_ASSERT(!"Should not be reached");
+ PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
return NULL;
}
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_log.c (294213 => 294214)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_log.c 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_log.c 2022-05-15 02:08:04 UTC (rev 294214)
@@ -35,6 +35,14 @@
pthread_t pas_thread_that_is_crash_logging;
+// Debug option to log to a file instead of stdout by default.
+// This does not affect pas_fd_stream.
+#define PAS_DEBUG_LOG_TO_SYSLOG 0
+
+#if PAS_DEBUG_LOG_TO_SYSLOG
+#include <sys/syslog.h>
+#endif
+
void pas_vlog_fd(int fd, const char* format, va_list list)
{
char buf[PAS_LOG_MAX_BYTES];
@@ -84,7 +92,13 @@
void pas_vlog(const char* format, va_list list)
{
+#if PAS_DEBUG_LOG_TO_SYSLOG
+PAS_IGNORE_WARNINGS_BEGIN("format-nonliteral")
+ syslog(LOG_WARNING, format, list);
+PAS_IGNORE_WARNINGS_END
+#else
pas_vlog_fd(PAS_LOG_DEFAULT_FD, format, list);
+#endif
}
void pas_log(const char* format, ...)
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_utils.c (294213 => 294214)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_utils.c 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_utils.c 2022-05-15 02:08:04 UTC (rev 294214)
@@ -36,6 +36,53 @@
#include <stdio.h>
#include <unistd.h>
+#if PAS_X86_64
+
+#define CRASH_INST "int3"
+
+#define CRASH_GPR0 "r11"
+#define CRASH_GPR1 "r10"
+#define CRASH_GPR2 "r9"
+#define CRASH_GPR3 "r8"
+#define CRASH_GPR4 "r15"
+#define CRASH_GPR5 "r14"
+#define CRASH_GPR6 "r13"
+
+#elif PAS_ARM64
+
+#define CRASH_INST "brk #0xc471"
+
+#define CRASH_GPR0 "x16"
+#define CRASH_GPR1 "x17"
+#define CRASH_GPR2 "x18"
+#define CRASH_GPR3 "x19"
+#define CRASH_GPR4 "x20"
+#define CRASH_GPR5 "x21"
+#define CRASH_GPR6 "x22"
+
+#endif
+
+#if PAS_X86_64 || PAS_ARM64
+
+PAS_NEVER_INLINE PAS_NO_RETURN static void pas_crash_with_info_impl(uint64_t reason, uint64_t misc1, uint64_t misc2, uint64_t misc3, uint64_t misc4, uint64_t misc5, uint64_t misc6)
+{
+ register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
+ register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
+ register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
+ register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
+ register uint64_t misc4GPR asm(CRASH_GPR4) = misc4;
+ register uint64_t misc5GPR asm(CRASH_GPR5) = misc5;
+ register uint64_t misc6GPR asm(CRASH_GPR6) = misc6;
+ __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR), "r"(misc6GPR));
+ __builtin_trap();
+}
+
+#else
+
+PAS_NEVER_INLINE PAS_NO_RETURN static void pas_crash_with_info_impl(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t) { __builtin_trap(); }
+
+#endif
+
void pas_panic(const char* format, ...)
{
static const bool fast_panic = false;
@@ -44,6 +91,7 @@
pas_log("[%d] pas panic: ", getpid());
va_start(arg_list, format);
pas_vlog(format, arg_list);
+ pas_crash_with_info_impl((uint64_t)format, 0, 0, 0, 0, 0, 0);
}
__builtin_trap();
}
@@ -57,9 +105,18 @@
void pas_assertion_failed_no_inline(const char* filename, int line, const char* function, const char* _expression_)
{
- pas_panic("%s:%d: %s: assertion %s failed.\n", filename, line, function, _expression_);
+ pas_log("[%d] pas assertion failed: ", getpid());
+ pas_log("%s:%d: %s: assertion %s failed.\n", filename, line, function, _expression_);
+ pas_crash_with_info_impl((uint64_t)filename, line, (uint64_t) function, (uint64_t) _expression_, 0xbeefbff0, 42, 1337);
}
+void pas_assertion_failed_no_inline_with_extra_detail(const char* filename, int line, const char* function, const char* _expression_, uint64_t extra)
+{
+ pas_log("[%d] pas assertion failed (with extra detail): ", getpid());
+ pas_log("%s:%d: %s: assertion %s failed. Extra data: %llu.\n", filename, line, function, _expression_, extra);
+ pas_crash_with_info_impl((uint64_t)filename, line, (uint64_t) function, (uint64_t) _expression_, extra, 1337, 0xbeef0bff);
+}
+
void pas_panic_on_out_of_memory_error()
{
__builtin_trap();
Modified: trunk/Source/bmalloc/libpas/src/libpas/pas_utils.h (294213 => 294214)
--- trunk/Source/bmalloc/libpas/src/libpas/pas_utils.h 2022-05-15 00:47:31 UTC (rev 294213)
+++ trunk/Source/bmalloc/libpas/src/libpas/pas_utils.h 2022-05-15 02:08:04 UTC (rev 294214)
@@ -202,6 +202,7 @@
#endif /* PAS_ENABLE_TESTING -> so end of !PAS_ENABLE_TESTING */
PAS_API PAS_NO_RETURN PAS_NEVER_INLINE void pas_assertion_failed_no_inline(const char* filename, int line, const char* function, const char* _expression_);
+PAS_API PAS_NO_RETURN PAS_NEVER_INLINE void pas_assertion_failed_no_inline_with_extra_detail(const char* filename, int line, const char* function, const char* _expression_, uint64_t extra);
PAS_IGNORE_WARNINGS_BEGIN("missing-noreturn")
static PAS_ALWAYS_INLINE void pas_assertion_failed_noreturn_silencer(
@@ -241,6 +242,15 @@
pas_assertion_failed_no_inline(__FILE__, __LINE__, __PRETTY_FUNCTION__, #exp); \
} while (0)
+#define PAS_ASSERT_WITH_EXTRA_DETAIL(exp, extra) \
+ do { \
+ if (!PAS_ENABLE_ASSERT) \
+ break; \
+ if (PAS_LIKELY(exp)) \
+ break; \
+ pas_assertion_failed_no_inline_with_extra_detail(__FILE__, __LINE__, __PRETTY_FUNCTION__, #exp, extra); \
+ } while (0)
+
static inline bool pas_is_power_of_2(uintptr_t value)
{
return value && !(value & (value - 1));