Changeset 294214 in webkit


Ignore:
Timestamp:
May 14, 2022 7:08:04 PM (2 years ago)
Author:
Justin Michaud
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:
Location:
trunk/Source/bmalloc
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/bmalloc/ChangeLog

    r293952 r294214  
     12022-05-14  Justin Michaud  <justin_michaud@apple.com>
     2
     3        [LIBPAS] Add extra assert information to malloc enumeration API
     4        https://bugs.webkit.org/show_bug.cgi?id=240292
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        In the heap enumerator (which is a slow path), we have asserts that
     9        have the opportunity to include extra information to aid debugging.
     10
     11        We add PAS_ASSERT_WITH_DETAIL, which stuffs extra data into registers before crashing
     12        so that we can see it in crash logs. We also add a debugging option to allow logging
     13        to syslog, for cases when we do not have access to stdout.
     14
     15        * libpas/src/libpas/pas_enumerate_segregated_heaps.c:
     16        (consider_allocator):
     17        * libpas/src/libpas/pas_local_allocator_config_kind.h:
     18        (pas_local_allocator_config_kind_create_normal):
     19        (pas_local_allocator_config_kind_create_primordial_partial):
     20        (pas_local_allocator_config_kind_create_bitfit):
     21        (pas_local_allocator_config_kind_get_segregated_page_config_kind):
     22        (pas_local_allocator_config_kind_get_bitfit_page_config_kind):
     23        (pas_local_allocator_config_kind_get_string):
     24        * libpas/src/libpas/pas_log.c:
     25        (pas_vlog):
     26        * libpas/src/libpas/pas_utils.c:
     27        (pas_crash_with_info_impl):
     28        (pas_panic):
     29        (pas_assertion_failed_no_inline):
     30        (pas_assertion_failed_no_inline_with_extra_detail):
     31        * libpas/src/libpas/pas_utils.h:
     32
    1332022-05-07  Mark Lam  <mark.lam@apple.com>
    234
  • trunk/Source/bmalloc/libpas/src/libpas/pas_enumerate_segregated_heaps.c

    r291328 r294214  
    604604        pas_log("Have allocator %p in page_ish = %p\n", allocator, (void*)allocator->page_ish);
    605605   
    606     PAS_ASSERT_WITH_DETAIL(!pas_local_allocator_config_kind_is_bitfit(allocator->config_kind));
     606    PAS_ASSERT_WITH_EXTRA_DETAIL(!pas_local_allocator_config_kind_is_bitfit(allocator->config_kind), allocator->config_kind);
    607607   
    608608    page_config = pas_segregated_page_config_kind_get_config(
  • trunk/Source/bmalloc/libpas/src/libpas/pas_local_allocator_config_kind.h

    r285789 r294214  
    8787#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
    8888    }
    89     PAS_ASSERT(!"Should not be reached");
     89    PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    9090    return (pas_local_allocator_config_kind)0;
    9191}
     
    101101#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
    102102    }
    103     PAS_ASSERT(!"Should not be reached");
     103    PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    104104    return (pas_local_allocator_config_kind)0;
    105105}
     
    115115#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
    116116    }
    117     PAS_ASSERT(!"Should not be reached");
     117    PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    118118    return (pas_local_allocator_config_kind)0;
    119119}
     
    130130#undef PAS_DEFINE_SEGREGATED_PAGE_CONFIG_KIND
    131131    default:
    132         PAS_ASSERT(!"Should not be reached");
     132        PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    133133        return (pas_segregated_page_config_kind)0;
    134134    }
     
    145145#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
    146146    default:
    147         PAS_ASSERT(!"Should not be reached");
     147        PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    148148        return (pas_bitfit_page_config_kind)0;
    149149    }
     
    171171#undef PAS_DEFINE_BITFIT_PAGE_CONFIG_KIND
    172172    }
    173     PAS_ASSERT(!"Should not be reached");
     173    PAS_ASSERT_WITH_EXTRA_DETAIL(!"Should not be reached", kind);
    174174    return NULL;
    175175}
  • trunk/Source/bmalloc/libpas/src/libpas/pas_log.c

    r284895 r294214  
    3535
    3636pthread_t pas_thread_that_is_crash_logging;
     37
     38// Debug option to log to a file instead of stdout by default.
     39// This does not affect pas_fd_stream.
     40#define PAS_DEBUG_LOG_TO_SYSLOG 0
     41
     42#if PAS_DEBUG_LOG_TO_SYSLOG
     43#include <sys/syslog.h>
     44#endif
    3745
    3846void pas_vlog_fd(int fd, const char* format, va_list list)
     
    8593void pas_vlog(const char* format, va_list list)
    8694{
     95#if PAS_DEBUG_LOG_TO_SYSLOG
     96PAS_IGNORE_WARNINGS_BEGIN("format-nonliteral")
     97    syslog(LOG_WARNING, format, list);
     98PAS_IGNORE_WARNINGS_END
     99#else
    87100    pas_vlog_fd(PAS_LOG_DEFAULT_FD, format, list);
     101#endif
    88102}
    89103
  • trunk/Source/bmalloc/libpas/src/libpas/pas_utils.c

    r291007 r294214  
    3737#include <unistd.h>
    3838
     39#if PAS_X86_64
     40
     41#define CRASH_INST "int3"
     42
     43#define CRASH_GPR0 "r11"
     44#define CRASH_GPR1 "r10"
     45#define CRASH_GPR2 "r9"
     46#define CRASH_GPR3 "r8"
     47#define CRASH_GPR4 "r15"
     48#define CRASH_GPR5 "r14"
     49#define CRASH_GPR6 "r13"
     50
     51#elif PAS_ARM64
     52
     53#define CRASH_INST "brk #0xc471"
     54
     55#define CRASH_GPR0 "x16"
     56#define CRASH_GPR1 "x17"
     57#define CRASH_GPR2 "x18"
     58#define CRASH_GPR3 "x19"
     59#define CRASH_GPR4 "x20"
     60#define CRASH_GPR5 "x21"
     61#define CRASH_GPR6 "x22"
     62
     63#endif
     64
     65#if PAS_X86_64 || PAS_ARM64
     66
     67PAS_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)
     68{
     69    register uint64_t reasonGPR asm(CRASH_GPR0) = reason;
     70    register uint64_t misc1GPR asm(CRASH_GPR1) = misc1;
     71    register uint64_t misc2GPR asm(CRASH_GPR2) = misc2;
     72    register uint64_t misc3GPR asm(CRASH_GPR3) = misc3;
     73    register uint64_t misc4GPR asm(CRASH_GPR4) = misc4;
     74    register uint64_t misc5GPR asm(CRASH_GPR5) = misc5;
     75    register uint64_t misc6GPR asm(CRASH_GPR6) = misc6;
     76    __asm__ volatile (CRASH_INST : : "r"(reasonGPR), "r"(misc1GPR), "r"(misc2GPR), "r"(misc3GPR), "r"(misc4GPR), "r"(misc5GPR), "r"(misc6GPR));
     77    __builtin_trap();
     78}
     79
     80#else
     81
     82PAS_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(); }
     83
     84#endif
     85
    3986void pas_panic(const char* format, ...)
    4087{
     
    4592        va_start(arg_list, format);
    4693        pas_vlog(format, arg_list);
     94        pas_crash_with_info_impl((uint64_t)format, 0, 0, 0, 0, 0, 0);
    4795    }
    4896    __builtin_trap();
     
    58106void pas_assertion_failed_no_inline(const char* filename, int line, const char* function, const char* expression)
    59107{
    60     pas_panic("%s:%d: %s: assertion %s failed.\n", filename, line, function, expression);
     108    pas_log("[%d] pas assertion failed: ", getpid());
     109    pas_log("%s:%d: %s: assertion %s failed.\n", filename, line, function, expression);
     110    pas_crash_with_info_impl((uint64_t)filename, line, (uint64_t) function, (uint64_t) expression, 0xbeefbff0, 42, 1337);
     111}
     112
     113void pas_assertion_failed_no_inline_with_extra_detail(const char* filename, int line, const char* function, const char* expression, uint64_t extra)
     114{
     115    pas_log("[%d] pas assertion failed (with extra detail): ", getpid());
     116    pas_log("%s:%d: %s: assertion %s failed. Extra data: %llu.\n", filename, line, function, expression, extra);
     117    pas_crash_with_info_impl((uint64_t)filename, line, (uint64_t) function, (uint64_t) expression, extra, 1337, 0xbeef0bff);
    61118}
    62119
  • trunk/Source/bmalloc/libpas/src/libpas/pas_utils.h

    r293952 r294214  
    203203
    204204PAS_API PAS_NO_RETURN PAS_NEVER_INLINE void pas_assertion_failed_no_inline(const char* filename, int line, const char* function, const char* expression);
     205PAS_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);
    205206
    206207PAS_IGNORE_WARNINGS_BEGIN("missing-noreturn")
     
    240241            break; \
    241242        pas_assertion_failed_no_inline(__FILE__, __LINE__, __PRETTY_FUNCTION__, #exp); \
     243    } while (0)
     244
     245#define PAS_ASSERT_WITH_EXTRA_DETAIL(exp, extra) \
     246    do { \
     247        if (!PAS_ENABLE_ASSERT) \
     248            break; \
     249        if (PAS_LIKELY(exp)) \
     250            break; \
     251        pas_assertion_failed_no_inline_with_extra_detail(__FILE__, __LINE__, __PRETTY_FUNCTION__, #exp, extra); \
    242252    } while (0)
    243253
Note: See TracChangeset for help on using the changeset viewer.