Hi all, I'm writing a kernel module, and am trying to implement some exception-handling mechanism so that the system won't oops/panic if my module does e.g. a NULL dereference. The (horribly hackish) way I'm doing this right now is registering a die_notifier which will set the 'panic_on_oops' variable to 0 if we detect that the current PID corresponds to my module. However, this is ugly for many reasons. What would be the "standard" way of doing this? Is there something like Window's try/except blocks, where I can get back control of the execution flow, without having the process die? I'm aware of _ASM_EXTABLE, but I understand this only works for a single instruction and has other limitations.
On Thu, 17 Oct 2019 10:37:09 -0300, Martin Galvan said:
module does e.g. a NULL dereference. The (horribly hackish) way I'm doing this right now is registering a die_notifier which will set the 'panic_on_oops' variable to 0 if we detect that the current PID corresponds to my module. However, this is ugly for many reasons.
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; } Also, "current PID" and "my module" aren't two things that can correspond.... For double bonus points - this sort of "ignore the error if it's my process" means that any other user can trigger the situation - and crash the system.
El jue., 17 oct. 2019 a las 19:13, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; }
goto statements are harmful. In any case, what I meant was to have some sort of safety net to prevent exceptions (i.e. if I screw up and forget a NULL check) from panicking the system.
Also, "current PID" and "my module" aren't two things that can correspond....
I don't understand what you mean by that. Module code (e.g. an ioctl) runs as some process. In the case of an ioctl, I'd assume it's the same PID of the user process.
On Fri, Oct 18, 2019 at 4:44 PM Martin Galvan <omgalvan.86@gmail.com> wrote:
El jue., 17 oct. 2019 a las 19:13, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; }
goto statements are harmful. In any case, what I meant was to have some sort of safety net to prevent exceptions (i.e. if I screw up and forget a NULL check) from panicking the system.
Why exactly are goto statements harmful? Here is Linus's email about goto. https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel...
Also, "current PID" and "my module" aren't two things that can correspond....
I don't understand what you mean by that. Module code (e.g. an ioctl) runs as some process. In the case of an ioctl, I'd assume it's the same PID of the user process.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- Thank you Warm Regards Anuz
Edsger Dijkstra will haunt is forever, it seems. Gotos are just a tool, and this is one of the few places they're the best tool for the job. And generally in-kernel the acceptable method is to not forget a null check, as Valdis mentioned. It's cool to forget a null check on your own machine (who among us hasn't?) but if you're contributing/shipping code you gotta know that those pointers are good. On Fri, Oct 18, 2019, 11:44 Martin Galvan <omgalvan.86@gmail.com> wrote:
El jue., 17 oct. 2019 a las 19:13, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; }
goto statements are harmful. In any case, what I meant was to have some sort of safety net to prevent exceptions (i.e. if I screw up and forget a NULL check) from panicking the system.
Also, "current PID" and "my module" aren't two things that can correspond....
I don't understand what you mean by that. Module code (e.g. an ioctl) runs as some process. In the case of an ioctl, I'd assume it's the same PID of the user process.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On 18/10/2019 17:43, Martin Galvan wrote:> El jue., 17 oct. 2019 a las 19:13, Valdis Klētnieks
(<valdis.kletnieks@vt.edu>) escribió:
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; }
goto statements are harmful. In any case, what I meant was to have some sort of safety net to prevent exceptions (i.e. if I screw up and You actually want speed in the kernel and not necessarily extra effort for "try" and "catch" which is - sooner or later - never really used. And the "safety net" reduces the motivation to actually fix pointer bugs ....
forget a NULL check) from panicking the system.
Also, "current PID" and "my module" aren't two things that can correspond....
I don't understand what you mean by that. Module code (e.g. an ioctl) runs as some process. In the case of an ioctl, I'd assume it's the A ioctl-handler runs in the context/on behalf/... of a process (read: a user-space process/thread has called a syscall).
same PID of the user process. And there may be other code in your module which doesn't run on behalf of a process/thread, e.g. triggered by a timer, hardware IRQ, ...
So in general you don't have a "process" or "thread", only in some situations.... MfG, Bernd -- "I dislike type abstraction if it has no real reason. And saving on typing is not a good reason - if your typing speed is the main issue when you're coding, you're doing something seriously wrong." - Linus Torvalds
El vie., 18 oct. 2019 a las 13:05, Bernd Petrovitsch (<bernd@petrovitsch.priv.at>) escribió:
You actually want speed in the kernel and not necessarily extra effort for "try" and "catch" which is - sooner or later - never really used. And the "safety net" reduces the motivation to actually fix pointer bugs ....
I don't think I was clear. My intent is that if a pointer bug isn't fixed, my module will fail gracefully and go through the catch block instead of panicking the whole system. I don't see how this would stop me from fixing the bug itself; if anything, it could even help me debug it.
A ioctl-handler runs in the context/on behalf/... of a process (read: a user-space process/thread has called a syscall).
Yes.
And there may be other code in your module which doesn't run on behalf of a process/thread, e.g. triggered by a timer, hardware IRQ, ...
That's an interesting point. Yes, my die_notifier will run in exception context, but current->pid will still match that of the process which triggered the exception. I don't know if this happens by definition or it's just a coincidence, but it seems to work.
On 18/10/2019 18:11, Martin Galvan wrote:
El vie., 18 oct. 2019 a las 13:05, Bernd Petrovitsch (<bernd@petrovitsch.priv.at>) escribió:
You actually want speed in the kernel and not necessarily extra effort for "try" and "catch" which is - sooner or later - never really used.
Just brainstorming (as I'm not a guru on the inner workings): I don't know if it's possible to hook into the relevant IRQs etc. to catch a "kernel-space seg-fault" ....
And the "safety net" reduces the motivation to actually fix pointer bugs ....
I don't think I was clear. My intent is that if a pointer bug isn't fixed, my module will fail gracefully and go through the catch block
If the module fails "gracefully" other powers may decide that you should just paper over the bug and make you work on other stuff. Of course it doesn't inhibit any bug fix per se but ....
instead of panicking the whole system. I don't see how this would stop
Hmm, depending on the driver/module, one could use UML or VBox/VMware/... for testing - and the panic shows the exact place (or at least should;-). If it's a driver for real hardware, I hope you have a separate system to test;-)
me from fixing the bug itself; if anything, it could even help me debug it.
MfG, Bernd -- "I dislike type abstraction if it has no real reason. And saving on typing is not a good reason - if your typing speed is the main issue when you're coding, you're doing something seriously wrong." - Linus Torvalds
On Fri, Oct 18, 2019 at 01:11:54PM -0300, Martin Galvan wrote:
El vie., 18 oct. 2019 a las 13:05, Bernd Petrovitsch (<bernd@petrovitsch.priv.at>) escribió:
You actually want speed in the kernel and not necessarily extra effort for "try" and "catch" which is - sooner or later - never really used. And the "safety net" reduces the motivation to actually fix pointer bugs ....
I don't think I was clear. My intent is that if a pointer bug isn't fixed, my module will fail gracefully and go through the catch block instead of panicking the whole system. I don't see how this would stop me from fixing the bug itself; if anything, it could even help me debug it.
I don't think you really understand what is going on here. On the kernel level you would never wrap up a process in another process in order to catch a mistake, and then do error correction. That method of programming is not appropriate for kernel level code where you are running everything on the hardware. You can test for a condition before you run the code, and use GOTO if you want, but you are not doing a Java like Catch and Throw.
A ioctl-handler runs in the context/on behalf/... of a process (read: a user-space process/thread has called a syscall).
Yes.
And there may be other code in your module which doesn't run on behalf of a process/thread, e.g. triggered by a timer, hardware IRQ, ...
That's an interesting point. Yes, my die_notifier will run in exception context, but current->pid will still match that of the process which triggered the exception. I don't know if this happens by definition or it's just a coincidence, but it seems to work.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www2.mrbrklyn.com/resources - Unpublished Archive http://www.coinhangout.com - coins! http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
El vie., 18 oct. 2019 a las 14:02, Ruben Safir (<ruben@mrbrklyn.com>) escribió:
I don't think you really understand what is going on here. On the kernel level you would never wrap up a process in another process in order to catch a mistake, and then do error correction. That method of programming is not appropriate for kernel level code where you are running everything on the hardware.
You can test for a condition before you run the code, and use GOTO if you want, but you are not doing a Java like Catch and Throw.
I'm not talking about running managed code in the kernel. I'm talking about whether there is a more general version of something like _ASM_EXTABLE, or maybe even doing something like what Windows does with its __try/__except machinery which uses stack unwinding information.
From the responses here it's clear that there's no such thing in the kernel, at least that you guys know about. Thanks.
On 10/18/19 1:05 PM, Martin Galvan wrote:
El vie., 18 oct. 2019 a las 14:02, Ruben Safir (<ruben@mrbrklyn.com>) escribió:
I don't think you really understand what is going on here. On the kernel level you would never wrap up a process in another process in order to catch a mistake, and then do error correction. That method of programming is not appropriate for kernel level code where you are running everything on the hardware.
You can test for a condition before you run the code, and use GOTO if you want, but you are not doing a Java like Catch and Throw.
I'm not talking about running managed code in the kernel. I'm talking about whether there is a more general version of something like _ASM_EXTABLE, or maybe even doing something like what Windows does with its __try/__except machinery which uses stack unwinding information.
From the responses here it's clear that there's no such thing in the kernel, at least that you guys know about. Thanks.
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
https://code.woboq.org/linux/linux/arch/x86/include/asm/uaccess.h.html it is for user space coding... -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On 10/18/19 1:05 PM, Martin Galvan wrote:
Windows does with its __try/__except machinery which uses stack unwinding information.
Nothing would suprise we with MS. Interesting. Show me a code example for this within the MS WIndows kernel -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On 10/18/19 2:53 PM, Ruben Safir wrote:
On 10/18/19 1:05 PM, Martin Galvan wrote:
Windows does with its __try/__except machinery which uses stack unwinding information.
Nothing would suprise we with MS.
Interesting. Show me a code example for this within the MS WIndows kernel
https://www.oracle.com/technetwork/server-storage/solaris/dtrace-tutorial-14... fwiw -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On Fri, 18 Oct 2019 13:11:54 -0300, Martin Galvan said:
I don't think I was clear. My intent is that if a pointer bug isn't fixed, my module will fail gracefully and go through the catch block instead of panicking the whole system.
Well..here's the thing. Unless you have "panic_on_oops" set, hitting a null pointer will usually *NOT* panic the whole system. In fact, that #0000 in the panic message is a counter of how many times the kernel has OOPs'ed already. Way back in the dark mists of time, I had a system that managed to get it up to #1500 or so overnight. The problem is that at that point, a generic "fail gracefully" isn't really an option. The most graceful generic thing the kernel can do at that point is kill the execution thread that hit the error. This can quickly go sideways if that thread held a lock or similar critical resource. And no, even though the kernel knows all the locks the thread had, it *does not* know which ones, if any, are safe to unlock. The answer is probably "none of them", because locks are usually around the smallest amount of code possible, so if the lock was held, it's probably unsafe to break it. The few places in the kernel that do lock-breaking are basically all things like the printk/sysrq code that is basically a "we're dead anyhow, try to get some logging info". I've seen systems that manage to get the load average up to 17,000 or so, because process after process got into 'D' state because they tried to do filesystem I/O to a filesystem that had a lock wedged when a process oopsed. (A good reason for production systems to have lots of filesystems - if a kernel bug causes the /apps/database/logs filesystem to hang, you can probably reboot and recover because /apps/database/replay is synced to disk, and you have lots of stuff in /var that's got forensic info in it. Use one big filesystem, and when it locks up, you're immediately dead in the water. Might not even be able to ssh in, because that hangs because it writes to /var which is wedged along with everything else....) And if you actually *think* about it - a 'try/catch' is semantically *identical* to coding a parameter test before the event or checking a return code after. (A good place to interject Tom Duff's First Law of Systems Programming - "Never test for an error condition you don't know how to handle". Note in this context, "kill the thread and pray" means you *do* know how to handle it - by killing the thread...) Also - say you have a try/catch around a statement. For some exceptions, such as an end-of-file or a dropped network connection, it's reasonably easy to know how to clean up and continue. But what if the statement hits a null pointer error. What do you do to clean things up? You have a bad pointer, and you have *no way to actually fix it and continue normally*. And don't get me started on try/catch/throw - that's got even *more* land mines. :)
Hi Valdis, thanks for the thorough response. El vie., 18 oct. 2019 a las 18:53, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
Well..here's the thing. Unless you have "panic_on_oops" set, hitting a null pointer will usually *NOT* panic the whole system. In fact, that #0000 in the panic message is a counter of how many times the kernel has OOPs'ed already. Way back in the dark mists of time, I had a system that managed to get it up to #1500 or so overnight.
Yes, and this is why my horribly hackish way to fix things is to manually tamper with panic_on_oops on a die_notifier. I was hoping to find a way not to do this.
The most graceful generic thing the kernel can do at that point is kill the execution thread that hit the error. This can quickly go sideways if that thread held a lock or similar critical resource. And no, even though the kernel knows all the locks the thread had, it *does not* know which ones, if any, are safe to unlock.
I'd rather have the kernel just return control to me, at the beginning of the catch block, and give me a chance to fix things (or at least log some debugging info). I imagine that's what Windows' __except block is for. The kernel may not know which locks are safe to break, but I do. Whether a kernel left in an unstable state is less desirable than a panic is debatable in a case-by-case basis, and IMHO outside the scope of this discussion.
And if you actually *think* about it - a 'try/catch' is semantically *identical* to coding a parameter test before the event or checking a return code after.
I humbly disagree. Return codes aren't possible in all cases, which is why there are things like native_read_msr_safe which implement some form of exception handling through _ASM_EXTABLE.
Also - say you have a try/catch around a statement. For some exceptions, such as an end-of-file or a dropped network connection, it's reasonably easy to know how to clean up and continue. But what if the statement hits a null pointer error. What do you do to clean things up? You have a bad pointer, and you have *no way to actually fix it and continue normally*.
But then I can choose to let my process die, plus log some useful info and maybe even do some minor cleanups, without raising a panic. My particular module just reads some hardware registers and returns the info to userspace, so it's not something essential for the system. As a user, I would hate it if a non-essential module crashes the whole system like that. Perhaps the real problem is that panic_on_oops affects all of the kernel, rather than a given module. In any case, I think I already have my answer. Thanks for the response & discussion.
On Fri, Oct 18, 2019 at 07:09:54PM -0300, Martin Galvan wrote:
Hi Valdis, thanks for the thorough response.
El vie., 18 oct. 2019 a las 18:53, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
Well..here's the thing. Unless you have "panic_on_oops" set, hitting a null pointer will usually *NOT* panic the whole system. In fact, that #0000 in the panic message is a counter of how many times the kernel has OOPs'ed already. Way back in the dark mists of time, I had a system that managed to get it up to #1500 or so overnight.
Yes, and this is why my horribly hackish way to fix things is to manually tamper with panic_on_oops on a die_notifier. I was hoping to find a way not to do this.
Yes, please never do that. Just check for an error code (and there always will be one, if not, you are doing something wrong), and handle it properly. Yes, it's not easy, but this is the kernel, that goes without saying :)
I'd rather have the kernel just return control to me, at the beginning of the catch block, and give me a chance to fix things (or at least log some debugging info). I imagine that's what Windows' __except block is for. The kernel may not know which locks are safe to break, but I do.
Never break a lock, again, you are doing something wrong if that is needed.
And if you actually *think* about it - a 'try/catch' is semantically *identical* to coding a parameter test before the event or checking a return code after.
I humbly disagree. Return codes aren't possible in all cases, which is why there are things like native_read_msr_safe which implement some form of exception handling through _ASM_EXTABLE.
In Linux, where is a return code not possible?
But then I can choose to let my process die, plus log some useful info and maybe even do some minor cleanups, without raising a panic. My particular module just reads some hardware registers and returns the info to userspace, so it's not something essential for the system. As a user, I would hate it if a non-essential module crashes the whole system like that. Perhaps the real problem is that panic_on_oops affects all of the kernel, rather than a given module.
Modules are not processes, it's not a correct mapping at all. Modules are code, that's it. If all you are doing is reading hardware registers, you shouldn't have to worry about any of this, that should be a very tiny and simple module. Wait, what registers are you reading that we don't already support from userspace today? thanks, greg k-h
On 10/18/19 11:43 AM, Martin Galvan wrote:
goto statements are harmful
not in the kernel. -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On Fri, 2019-10-18 at 12:43 -0300, Martin Galvan wrote:
El jue., 17 oct. 2019 a las 19:13, Valdis Klētnieks (<valdis.kletnieks@vt.edu>) escribió:
For starters, the *correct* in-kernel way to deal with this is: if (!ptr) { printk("You blew it!\n"); goto you_blew_it; }
goto statements are harmful. In any case, what I meant was to have some sort of safety net to prevent exceptions (i.e. if I screw up and forget a NULL check) from panicking the system.
https://koblents.com/Ches/Links/Month-Mar-2013/20-Using-Goto-in-Linux-Kernel...
Also, "current PID" and "my module" aren't two things that can correspond....
I don't understand what you mean by that. Module code (e.g. an ioctl) runs as some process. In the case of an ioctl, I'd assume it's the same PID of the user process.
Every time you test whether the PID is the PID of the currently running process, it will be true. Think of the kernel as a privileged shared library, not as a program that userspace happens to communicate with. -- All Rights Reversed.
On 10/18/19 5:24 PM, Rik van Riel wrote:
Every time you test whether the PID is the PID of the currently running process, it will be true. Think of the kernel as a privileged shared library, not as a program that userspace happens to communicate with.
this last sentence can not be true. I have a running scheduler that listens for interupts and reads processes to run in a cue. -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On 10/18/19 5:24 PM, Rik van Riel wrote:
Every time you test whether the PID is the PID of the currently running process, it will be true. Think of the kernel as a privileged shared library, not as a program that userspace happens to communicate with.
https://superuser.com/questions/197168/is-kernel-a-process -- So many immigrant groups have swept through our town that Brooklyn, like Atlantis, reaches mythological proportions in the mind of the world - RI Safir 1998 http://www.mrbrklyn.com DRM is THEFT - We are the STAKEHOLDERS - RI Safir 2002 http://www.nylxs.com - Leadership Development in Free Software http://www.brooklyn-living.com Being so tracked is for FARM ANIMALS and extermination camps, but incompatible with living as a free human being. -RI Safir 2013
On Fri, 18 Oct 2019 12:43:58 -0300, Martin Galvan said:
goto statements are harmful.
For starters, note that the original paper was written in 1968. Yes, it's over a half century old now. Have you actually *read* the paper? https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf You probably want to keep in mind that in 1968, most languages in widespread use (in other words, Fortran and COBOL, effectively) did *not* have any concept *at all* of "structured programming" supported by language syntax. Fortran had exactly one explicit iterative syntax, the DO loop, which was a subset of the C for loop. It also had the infamous and dangerous 'arithmetic if' statement, which was of the format 'if (condition) A,B,C' - which was a *three* way goto to labels A B or C depending if 'condition' was negative, zero, or positive. Yes, this meant that the following statement *had* to have a goto target label on it in order to be reachable code. There was also 'GOTO A,B,C,...,integer variable', which would branch to label A if the variable was 1, B if it was 2, etc... And the creeping horror known as 'assigned goto'. ASSIGN 10 TO N ... GO TO N ( 10, 20, 30, 40 ) ... 10 CONTINUE ... 40 STOP Now imagine a large subroutine that takes most of a box of punched cards, and 5 or 6 different variables containing assigned targets, and the GOTO can branch to *anywhere* in the current compilation unit. (If that isn't bad enough, the IBM Fortran IV G compiler included an extension called 'debug units', which *really* *did* have the semantics of the joke statement 'COME FROM'.) Fortran wouldn't get a 'while' for another 15 years or so. And the COBOL 'PERFORM' verb is best not approached without first fortifying yourself with strong drink. That was the reality that Dijkstra was writing about at the time. Also consider where Dijkstra's head was when he wrote the paper, which also includes this statement: "Let us now consider repetition clauses (like, while B repeat A or repeat A until B). Logically speaking, such clauses are now superfluous, bcause we can express repetition with the aid of recursive procedures." Yeah. Exactly. Let's return to 2019. Feel free to look at function hi_command() in drivers/media/dvb-frontends/drx39xyj/drxj.c and re-write it in standard nested if/then/elseif/then/elsif/then... form. Watch out for the fact that the case statement uses fallthroughs. Let us know the maximum number of leading tabs your version uses. Another good challenge is to unsnarl the gotos in the TLV_PUT macros in fs/btrfs/send.c into a form that doesn't use goto. There's plenty of good reason to use goto's when implementing a finite state machine. At some point, purity needs to take a back seat to pragmatism.
Martin Galvan <omgalvan.86@gmail.com> writes:
I'm writing a kernel module, and am trying to implement some exception-handling mechanism so that the system won't oops/panic if my module does e.g. a NULL dereference.
Why don't you test your pointer for NULL instead? Sounds like a hell of a lot simpler solution to me. But I'm probably missing something as usual... Bjørn
participants (9)
-
Anuz Pratap Singh Tomar -
Bernd Petrovitsch -
Bjørn Mork -
Greg KH -
Maria Neptune -
Martin Galvan -
Rik van Riel -
Ruben Safir -
Valdis Klētnieks