Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Malloc is not reentrant?

by floopy (Sexton)
on Apr 28, 2000 at 11:05 UTC ( [id://9553]=perlquestion: print w/replies, xml ) Need Help??

floopy has asked for the wisdom of the Perl Monks concerning the following question:

I know this isn't REALLY a Perl question, but I find it quite interesting anyways:

According to p. 55 of "Advanced Perl Programming" malloc is not reentrant and the implication the book lists is that if one is calling a function and the program receives a signal which calls the same function "the function gets totally confused and is likely to crash the system."
What exactly does this mean?
If ANY program is in a malloc block and a hardware interrupt occurs and the interrupt handler uses malloc, do problems occur? Or do interrupt handlers not use malloc then.
I suppose I would like to know why there is a problem w/ malloc ONLY in the specific case Sriram Srinivasan listed.


thanks.

I get the feeling I slept through an important lecture a while ago :)

Replies are listed 'Best First'.
Re: Malloc is not reentrant?
by lhoward (Vicar) on Apr 28, 2000 at 18:58 UTC
    In general, the "non-reentrance" problem is only limited to a single process (i.e. an interrupt in one process will have no effect on another process, unless of-course the process is the kernel or some other really important piece of code).

    The easiest way to think about it is to consider function foo that uses a global variable (bar) to store some data. Now if foo is being called and has modified bar, and foo is called again (by the same process) before its first invocation is done bar may not be set properly and could cause foo to behave abnormally (the "totally confused and crashing" effect mentioned in "Advanced Perl Programming"). In most cases it will just cause a program error, but malloc is such so intimate w/ the system that a problem there could lead to overlapping blocks of allocated memory w/ another process, etc...

    Consider this (really bogus, but demonstrates the point) example:

    my $bar; sub foo{ $bar=time(); sleep 5; return $bar+20; }
    (for this example, pretend that signals don't mess up sleep calls, even though they do) Now when foo is called it will sleep for 5 seconds and return a time 20 seconds after it was called.. However, if foo were called, and during the sleep a signal caused foo to be called again the program wouldn't crash, but the first foo would return a wrong value (a value different from what it would have returned it it had not been interrupted).

    In non-threaded programming this problem is pretty-much limited to signal and exception handlers. However when you're dealing w/ a threaded application you need to be very careful about possible code reentrance.

    In general in signal handlers you should not be doing much work.


    Les Howard
    www.lesandchris.com
    Author of Net::Syslog and Number::Spell

Re: Malloc is not reentrant?
by chromatic (Archbishop) on Apr 28, 2000 at 19:02 UTC
    It means that if you have a program that calls malloc() and it gets interrupted for another task that calls malloc(), there's no guarantee that the original call won't be thrashed by the second. An interesting link about glibc is here.

    Effectively, this comes up in Perl when you write your own signal handlers. As they're invoked via signals (interrupting the normal flow of operation), there's a possibility that another signal could come in as you are trying to deal with the first.

    That's still not a very effective explanation. Okay, think of it like spinning plates on sticks. You'll be better at it when you only have one to do. If you get interrupted while spinning one to go do another, you might have a crash a few moments later.

    (Get around this by doing as little as possible in your signal handlers.)

RE: Malloc is not reentrant?
by rmgiroux (Initiate) on Apr 28, 2000 at 19:16 UTC
    Basically, a routine is "reentrant" if you can interrupt it at any point in its execution, run it again from the interrupt (either a signal, or an interrupt handler, or another thread, although thread safety is tougher and different than reentrancy) and then resume the original execution later without problem.

    The issue with Perl signal handlers, as I understand it, is that the signals are delivered to your signal sub when they are received from the OS, even if Perl is in the middle of some other operation, like a hash update, or a substitution. It's possible that the operation you've interrupted was in a non-reentrant routine at the time, so if you do anything that causes that routine to be called, you're toast.

    What I understand from my (limited) reading of p5p is that signals are unsafe in all versions of perl for now. There also doesn't seem to be a consensus as to how to make them safe, so you should be very careful about how you use them. I get them impression that setting an integer scalar that already exists to a new (also integer) value is likely to work ok, most of the time. Everything else will depend.

    So you may have to settle for setting some "$signaled" flag that you then check in your main loop, for instance. Far from ideal. But better than blowing up, also...

    The p5p threads, BTW, also seem to say that malloc is not the only culprit, and one reason that this particular approach is not necessarily safe is that calling your signal handler involves a sub invocation, which may do non-reentrant things beyond your control.

    Good luck. I recommend the perl5-porters archive. Check out <A HREF="http://www.xray.mpe.mpg.de

RE: Malloc is not reentrant?
by rmgiroux (Initiate) on Apr 28, 2000 at 19:17 UTC
    Basically, a routine is "reentrant" if you can interrupt it at any point in its execution, run it again from the interrupt (either a signal, or an interrupt handler, or another thread, although thread safety is tougher and different than reentrancy) and then resume the original execution later without problem.

    The issue with Perl signal handlers, as I understand it, is that the signals are delivered to your signal sub when they are received from the OS, even if Perl is in the middle of some other operation, like a hash update, or a substitution. It's possible that the operation you've interrupted was in a non-reentrant routine at the time, so if you do anything that causes that routine to be called, you're toast.

    What I understand from my (limited) reading of p5p is that signals are unsafe in all versions of perl for now. There also doesn't seem to be a consensus as to how to make them safe, so you should be very careful about how you use them. I get them impression that setting an integer scalar that already exists to a new (also integer) value is likely to work ok, most of the time. Everything else will depend.

    So you may have to settle for setting some "$signaled" flag that you then check in your main loop, for instance. Far from ideal. But better than blowing up, also...

    Good luck. I recommend the perl5-porters archive. Check out this thread which indicated malloc isn't the only culprit. This summary is also very good.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://9553]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (2)
As of 2024-04-26 05:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found