From owner-freebsd-arch@FreeBSD.ORG Thu Sep 11 00:06:57 2008 Return-Path: Delivered-To: arch@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9B0791065678; Thu, 11 Sep 2008 00:06:57 +0000 (UTC) (envelope-from dillon@apollo.backplane.com) Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by mx1.freebsd.org (Postfix) with ESMTP id 66A0D8FC1A; Thu, 11 Sep 2008 00:06:57 +0000 (UTC) (envelope-from dillon@apollo.backplane.com) Received: from apollo.backplane.com (localhost [127.0.0.1]) by apollo.backplane.com (8.14.1/8.14.1) with ESMTP id m8B06vGD033200; Wed, 10 Sep 2008 17:06:57 -0700 (PDT) Received: (from dillon@localhost) by apollo.backplane.com (8.14.1/8.13.4/Submit) id m8B06vOU033199; Wed, 10 Sep 2008 17:06:57 -0700 (PDT) Date: Wed, 10 Sep 2008 17:06:57 -0700 (PDT) From: Matthew Dillon Message-Id: <200809110006.m8B06vOU033199@apollo.backplane.com> To: John Baldwin References: <200809101531.54646.jhb@FreeBSD.org> <200809102126.m8ALQxdK032024@apollo.backplane.com> <200809101806.38042.jhb@freebsd.org> Cc: arch@freebsd.org Subject: Re: PASSERT() - asserting for panics X-BeenThere: freebsd-arch@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussion related to FreeBSD architecture List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 11 Sep 2008 00:06:57 -0000 :I think part of the pollution is that what I really want to do is treat a :panic like an exception that I can catch. I could probably make that idiom :work with two macros so your code can be: : : PANIC_TRY { : /* do stuff */ : } PANIC_CATCH("foo"); : :That could potentially work with some evil goto's that jumped between the :macros (i.e. have the setjmp() in PANIC_CATCH and PANIC_TRY goto's down to :-- :John Baldwin Hmm. Almost java-like, where an exception pops back through subroutine levels until it finds a match. That kind of functionality would be a real mess in C. A limited form would be possible, something like this: #define PANIC_CATCH(label) \ (...) static jmpbuf label # _jmpbuf if (0) { for (;;) { longjmp(&label # _jmpbuf); label: #define PANIC_RETRY }} #define PANIC_PANIC panic(...); }} #define PASSERT(label, cond) \ (...) if (__predict_false(!(cond))) { setjmp (&label # _jmpbuf); goto label; } PANIC_CATCH(badthings) { ... PANIC_RETRY; } PANIC_CATCH(badthings) { ... PANIC_PANIC; } PASSERT(badthings, x == 1); Which would allow you some control over the context plus allow multiple PASSERT's with the same label. But, OMG I don't know about doing setjmp/longjmp in the kernel. I don't think it would be worth it. Theoretically one could cross procedural boundaries with the longjmp, and place the jmpbuf in a DATASET and have the kernel glue the longjmp address. That would be a candidate for the C obfuscation contest though. -Matt Matthew Dillon