Date: Wed, 13 Feb 2013 10:38:56 -0500 From: John Baldwin <jhb@freebsd.org> To: Kirk McKusick <mckusick@mckusick.com> Cc: Adrian Chadd <adrian@freebsd.org>, Christoph Mallon <christoph.mallon@gmx.de>, Andriy Gapon <avg@freebsd.org>, freebsd-arch@freebsd.org Subject: Re: Proposal: Unify printing the function name in panic messages() Message-ID: <201302131038.57250.jhb@freebsd.org> In-Reply-To: <201302120134.r1C1Ycfh026347@chez.mckusick.com> References: <201302120134.r1C1Ycfh026347@chez.mckusick.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, February 11, 2013 8:34:38 pm Kirk McKusick wrote: > I have recently gone down several ratholes trying to understand a > panic message which had the wrong function name (prefix ufs1_ instead > of ufs2_). I can definitely say that it matters to me. And I think > that fixing the problem as Christoph has outlined will be a big > step in the right direction. > > John, in your code you cannot expect to match the entire panic > string if it has any % formats in it. So to be useful, you must be > able to work with a constant subset of the string. The addition of > other information such as a function name at the start should not > affect that constant part that you are trying to match. Actually, that's not quite true. I store both the "raw" format string and a generated string in an on-stack buffer in the PANIC_TRY macro that is compared against. Some more examples: static int test_no_sleeping_recursion(void) { struct timespec before, after; int error; /* These tests will DROP_GIANT before panic'ing. */ DROP_GIANT(); THREAD_NO_SLEEPING(); PANIC_TRY { tsleep(&test_wchan, 0, "sleep", 1); } PANIC_CATCH { sleepq_release(&test_wchan); IGNORE_PANIC("%s: td %p to sleep on wchan %p with sleeping prohibited"); } PANIC_END; THREAD_NO_SLEEPING(); PANIC_TRY { tsleep(&test_wchan, 0, "sleep", 1); } PANIC_CATCH { sleepq_release(&test_wchan); IGNORE_PANIC("%s: td %p to sleep on wchan %p with sleeping prohibited"); } PANIC_END; THREAD_SLEEPING_OK(); PANIC_TRY { tsleep(&test_wchan, 0, "sleep", 1); } PANIC_CATCH { sleepq_release(&test_wchan); IGNORE_PANIC("%s: td %p to sleep on wchan %p with sleeping prohibited"); } PANIC_END; THREAD_SLEEPING_OK(); nanouptime(&before); error = tsleep(&test_wchan, 0, "sleep", hz); nanouptime(&after); KASSERT(error == EWOULDBLOCK, ("tsleep did not timeout: %d", error)); PICKUP_GIANT(); return (TEST_OK); } UNIT_TEST("sleeping disabled recursion", test_no_sleeping_recursion); (This panic already use __func__ explicitly) And my unit tests for PANIC_TRY itself: static int catch_panics(void) { PANIC_TRY { panic("test"); } PANIC_CATCH { IGNORE_PANIC("test"); } PANIC_END; PANIC_TRY { panic("test longer message"); } PANIC_CATCH { IGNORE_PANIC_STARTS_WITH("test"); } PANIC_END; PANIC_TRY { panic("test %s", "raw message"); } PANIC_CATCH { IGNORE_PANIC("test %s"); } PANIC_END; PANIC_TRY { panic("test %s", "formatted message"); } PANIC_CATCH { IGNORE_PANIC("test formatted message"); } PANIC_END; return (TEST_OK); } UNIT_TEST("catching panics", catch_panics); static int unexpected_panics(void) { PANIC_TRY { PANIC_TRY { panic("test"); } PANIC_CATCH { } PANIC_END; } PANIC_CATCH { IGNORE_PANIC_STARTS_WITH("Unexpected panic"); } PANIC_END; PANIC_TRY { PANIC_TRY { panic("foo"); } PANIC_CATCH { IGNORE_PANIC("bar"); IGNORE_PANIC_STARTS_WITH("b"); } PANIC_END; } PANIC_CATCH { IGNORE_PANIC_STARTS_WITH("Unexpected panic"); } PANIC_END; return (TEST_OK); } UNIT_TEST("unexpected panics", unexpected_panics); TESTER_MODULE(panic); If every panic has a slightly '%s:' at the front that is perhaps less painful to deal with in the unformatted case. In the case that you want a test to catch a formatted message then it's a bit less obvious you need to prepend the relevant function name. -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201302131038.57250.jhb>