From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1El4W0-0001yB-B2 for mharc-grub-devel@gnu.org; Sat, 10 Dec 2005 08:11:52 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1El4Vu-0001w4-J0 for grub-devel@gnu.org; Sat, 10 Dec 2005 08:11:47 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1El4Vr-0001uS-R0 for grub-devel@gnu.org; Sat, 10 Dec 2005 08:11:44 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1El4Vq-0001u7-7M for grub-devel@gnu.org; Sat, 10 Dec 2005 08:11:42 -0500 Received: from [212.85.152.101] (helo=kotoba.storever.com) by monty-python.gnu.org with esmtp (Exim 4.34) id 1El4XD-00061J-4A for grub-devel@gnu.org; Sat, 10 Dec 2005 08:13:07 -0500 Received: from kotoba.storever.com (kotoba.oasis.nexedi.com [212.85.152.101]) by kotoba.storever.com (Postfix) with ESMTP id 2F96A3C8229C1 for ; Sat, 10 Dec 2005 14:31:03 +0100 (CET) Received: from ip6-localhost (localhost [127.0.0.1]) by kotoba.storever.com (Postfix) with ESMTP id 0AACE3C8229C0 for ; Sat, 10 Dec 2005 14:31:03 +0100 (CET) From: "Yoshinori K. Okuji" Organization: enbug.org To: The development of GRUB 2 Date: Sat, 10 Dec 2005 14:11:11 +0100 User-Agent: KMail/1.7.2 References: <4399FE01.7010402@nic.fi> <87mzj9q4z7.fsf@xs4all.nl> <439AA87B.9050607@nic.fi> In-Reply-To: <439AA87B.9050607@nic.fi> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200512101411.11612.okuji@enbug.org> X-Bogosity: No, tests=bogofilter, spamicity=0.500000, version=0.17.2 Subject: Re: problem in usage of grub_errno... X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 10 Dec 2005 13:11:50 -0000 On Saturday 10 December 2005 11:05 am, Vesa J=E4=E4skel=E4inen wrote: > Changing coding guide of using grub_errno we could probably get this > issue "working". But then there is still problem with lost error > messages if subsequent code fails with real error. > > If we just zero out grub_errno in code before printing out error(s). > Then the actual error message will get lost. So it is important not to > zero out spuriously grub_errno. > > Good way of checking for errors could be like: > -- > grub_errno_t rc; > > rc =3D function_that_could_fail (); > /* do some stuff here. */ > if (rc) > return rc; Please do not change it in this way. The error subsystem of GRUB is based o= n=20 the idea of exceptions, that is to say, passing an error to higher levels=20 until it is caught explicitly. This is similar to C++, Java, Python or Ruby= =2E=20 Unfortunately, C does not support exceptions directly, so we must emulate i= t.=20 So, what we must do is not to ignore an error where it happens. I use Python as an example. Suppose this code: def foo(): bar() def bar() baz() print 'bar' def baz() raise RuntimeError, 'baz' foo() When executing this, Python does not print 'bar', because the exception rai= sed=20 by baz is not caught by bar, and the control is immediately transferred to= =20 foo. In C, to emulate this behavior, we must do like this: void foo (void) { bar (); } void bar (void) { baz (); if (grub_errno !=3D GRUB_ERR_NONE) return; grub_printf ("bar\n"); } void baz (void) { grub_error (GRUB_ERR_SOMETHING, "baz"); } In other words, if you ignore an error set by calling a function and pass t= he=20 control to another, it violates the semantics. So, strictly speaking, you=20 must choose either of these when an error is set: =2D deciding to ignore the error explicitly by setting GRUB_ERRNO to=20 GRUB_ERR_NONE =2D handling the error by returning to the higher level or dealing with the= =20 error locally (e.g. printing the error) We (at least I) sometimes violate this rule by intention when knowing that = it=20 is safe to ignore an error, simply because it is too heavy to deal with=20 errors all the time. In your situation, things are a bit complicated. In my opinion, all you sho= uld=20 do is to save error information in a temporary place and reset it afterward= s.=20 =46or example, you can define a function like this: void grub_error_push (void) { /* Push the current error in a stack and clear GRUB_ERRNO. */ ... } void grub_error_pop (void) { /* Pop the previous error and set GRUB_ERRNO. */ ... } I don't know if this should be stack-based or flat. For example, you can=20 allocate space in a function and pass the pointer to a function which saves= =20 current error information. In this case, functions should be named=20 grub_error_save and grub_error_restore. The difficulty is that it is not very safe to use a heap to allocate space = to=20 store error information, because such a memory allocation can generate=20 another error (due to memory shortage). The possibility is low, but we must= =20 still consider it. One way is to allocate such space in advance. For example, if we use the=20 stack-based approach (personally I prefer this for consistency), instead of= =20 allocating space dynamically, we can allocate it statically. That is, at=20 linking time or at initialization time. This way limits the maximum number = of=20 slots arbitrarily, but it should be enough for the reality (e.g. 10). What do you think? Okuji