Title: [294214] trunk/Source/bmalloc
Revision
294214
Author
justin_mich...@apple.com
Date
2022-05-14 19:08:04 -0700 (Sat, 14 May 2022)

Log Message

[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:

Modified Paths

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));
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to