Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 'static' : strange behavior

Reply
Thread Tools

'static' : strange behavior

 
 
Ike Naar
Guest
Posts: n/a
 
      12-28-2010
On 2010-12-28, Mark <(E-Mail Removed)> wrote:
> I've posted the source of the routine under question at
> http://clc.pastebin.com/f4FRqgit


Unfortunately that code is uncompilable. It needs types (e.g. si_t)
that you haven't provided. Also, you don't show how the nvram_init
function is called from its environment.
Given the behaviour that you're seeing, it's not unlikely that there
is an error elsewhere in your program (outside the nvram_init function).
Please provide a minimal, but complete program that exhibits the
problematic behaviour, that we can compile and run.
 
Reply With Quote
 
 
 
 
Francois Grieu
Guest
Posts: n/a
 
      12-28-2010
On 28/12/2010 03:24, Mark wrote:
> Eric Sosman wrote:
>> Yes, a `static' variable retains its last-stored[*] value from
>> one function call to the next, or more generally from one assignment
>> to the next. If there has been no assignment, the `static' variable
>> holds it initialization value, or "the right kind of zero" if there
>> is no initializer. Based on what you've shown, `nvram_status' should
>> have the value minus one the first time nvram_init() is called. I
>> therefore suspect that you have not shown everything that's relevant.
>> In particular, you haven't shown how you determine the original value
>> of `nvram_status' -- and it's possible that the determination itself
>> might be at fault.

>
> I print the value of 'nvram_status', below is more complete snippet:
>
> int nvram_init (void *si)
> {
> int ret;
> static int nvram_status = -1;
>
> printf("%s : nvram_status=%d\n", __FUNCTION__, nvram_status); /* my line */
>
> if (nvram_status == 1) /* the very first statement in the original code */
> return 1;
>
> /* low-level initializations of NVRAM */
> /* nvram_status can be altered down here */
> ...
> }
>
>>[*] For a `volatile' variable, "last-stored" might not be a
>> visible action of the program: a hardware clock or some such might
>> "store" a new value in the variable without an explicit assignment by
>> the program. However, `nvram_status' is not `volatile', so we need
>> not consider that potential complication.


In some embedded environments, initialization of static and global
variables can be disabled or enabled depending on linking options
or input. One good reason is to be able to perform things quickly
enough before main() [hardware setup, RAM test, unamit]. Sometime,
this initialization is replaced or superseded by a "zero all RAM"
procedure. That would explain the behavior.

As an alternative, could it be the case that the debugging with
printf works only after a while, or not in the context where the
first nvram_init happens, so that first call is missed?

Francois Grieu
 
Reply With Quote
 
 
 
 
Nick
Guest
Posts: n/a
 
      12-28-2010
"Mark" <(E-Mail Removed)> writes:

> Eric Sosman wrote:
>> Yes, a `static' variable retains its last-stored[*] value from
>> one function call to the next, or more generally from one assignment
>> to the next. If there has been no assignment, the `static' variable
>> holds it initialization value, or "the right kind of zero" if there
>> is no initializer. Based on what you've shown, `nvram_status' should
>> have the value minus one the first time nvram_init() is called. I
>> therefore suspect that you have not shown everything that's relevant.
>> In particular, you haven't shown how you determine the original value
>> of `nvram_status' -- and it's possible that the determination itself
>> might be at fault.

>
> I print the value of 'nvram_status', below is more complete snippet:
>
> int nvram_init (void *si)
> {
> int ret;
> static int nvram_status = -1;
>
> printf("%s : nvram_status=%d\n", __FUNCTION__, nvram_status); /*
> my line */
>
> if (nvram_status == 1) /* the very first statement in the original
> code */
> return 1;
>
> /* low-level initializations of NVRAM */
> /* nvram_status can be altered down here */


I'd place a small bet that something somewhere else, that is executed
before nvram_init is called, has overwriten the space where nvram_status
is stored.

Because it's a static variable the compiler will have most likely
allocated it space as though it was a "global" variable - it just
restricts the scope the name is known in.

So if elsewhere you have something like:

char *fred;
....
int main(void) {
....
strcpy(fred,"test");

that could well be blowing you your nvram_status
--
Online waterways route planner | http://canalplan.eu
Plan trips, see photos, check facilities | http://canalplan.org.uk
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      12-28-2010


"Mark" <(E-Mail Removed)> wrote in message
news:ifbo5s$bnb$(E-Mail Removed)...
> Eric Sosman wrote:
>> It seems you like to dispense information drop by precious drop,
>> one tiny tidbit at a time. If the information is so very private that
>> you dare not share it except in meaningless driblets -- well, I have
>> never been known as a patient man, and I think I've got better things
>> to do than spend time wheedling details from a coy Twenty Questions
>> player.

>
>
> Appreciate your delightful sense of humour, it indeed cheered me up. The
> information isn't private at all, at first I thought the function is
> pretty lengthy to be posted here, therefore I provided just a snippet as
> you asked. I've posted the source of the routine under question at
> http://clc.pastebin.com/f4FRqgit


Since your printf statement also shows the address of nvram_status, and
assuming this will be consistent, try using that address to print the value
of nvram_status outside, and before calling, nvram_init. (Or just
temporarily move nvram_status outside the function.)

Or add the line nvram_status=-1 just after it's declaration; normally this
will be unnecessary. If it's value now is printed as -1, that suggests a
problem elsewhere.

(Or, just before it's declaration, perhaps add the line:

static int dummy=1234;

and try printing that in your printf() too, to see if has a similiar fate.)

Also, nvram_init() appears to be called recursively, which is unusual for
this sort of function. Probably not the cause of this bug, but I can see
subtle problems creeping in because each different invocation of
nvram_init() is modifying the same static variable.

--
Bartc

 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      12-28-2010
On 12/27/2010 11:13 PM, Mark wrote:
> Eric Sosman wrote:
>> It seems you like to dispense information drop by precious drop,
>> one tiny tidbit at a time. If the information is so very private that
>> you dare not share it except in meaningless driblets -- well, I have
>> never been known as a patient man, and I think I've got better things
>> to do than spend time wheedling details from a coy Twenty Questions
>> player.

>
>
> Appreciate your delightful sense of humour, it indeed cheered me up. The
> information isn't private at all, at first I thought the function is
> pretty lengthy to be posted here, therefore I provided just a snippet as
> you asked. I've posted the source of the routine under question at
> http://clc.pastebin.com/f4FRqgit


Well, you've moved past dribbling, but in order to help you we still
need more information than you've given so far. What you should give us
is the complete actual text of a stand-alone program (preferably as
small as possible) that can actually be compiled and executed to
demonstrate the problem you're asking about. You should identify the
environment where you compiled, linked, and executed the program, and
the precise commands you used to do the compiling an linking.

Your code is not compilable as it stands because it uses the following
identifiers without defining or declaring them, and also without
#including a header file that would define or declare them:

bool
crc_ver_init
embedded_nvram
magic
nvram_exit
nvram_do_reset
nvram_header
struct nvram_header
printf
si_t
uint32
FALSE
FLASH_MIN
KSEG1ADDR
NVRAM_MAGIC
NVRAM_SPACE
SI_FLASH2
SI_FLASH2_SZ
TRUE

It's possible to make reasonable guesses about what those identifiers
might mean, based both upon their names and upon how they are used.
However, the peculiar behavior of your program could easily depend upon
precisely how one of those identifiers is defined. In particular, if
you've made a mistake by using one of those identifiers in a way that's
incompatible with the way it's defined, that might be precisely whey the
behavior is so odd.

The behavior is undefined because the code makes use of the following
identifiers which are reserved to the implementation:

_nvram_init
_nvram_exit

If these are routines defined by the implementation, and used by your
program, then your program is portable only to implementations that
provide definitions for those identifiers which work in the way you
expect them to. You should identify where the definitions of those
functions comes from.

The fact that one of the two functions whose definition you have
provided is named nvram_init() opens up the question of whether
_nvram_init might be a typo for nvram_init (or vice versa).

Your code fails to demonstrate the problem because it does not, in
itself, constitute a complete program. That can easily be solved by
adding a main() which calls nvram_init(). However, you need to provide
us with that call; the reason why you're getting the odd results that
you see might be due to the context from which it was called.
 
Reply With Quote
 
Willem
Guest
Posts: n/a
 
      12-28-2010
Andrew Haley wrote:
) christian.bau <(E-Mail Removed)> wrote:
)>
)> void init_this (void) {
)> static int anarray [10];
)> int i; for (i = 0; i <= 10; ++i) anarray [i] = 0;
)> }
)
) Ahem. Surely I cannot be the only person to have noticed this
) mistake, which explains everything...

Of course you're not. The person you're replying to, who wrote this code,
saying it was an example of undefined behaviour which could cause an effect
similar to what the OP described, is obviously very aware of the mistake,
as he made it on purpose for the exact purpose of creating the example.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
Reply With Quote
 
Geoff
Guest
Posts: n/a
 
      12-28-2010
On Tue, 28 Dec 2010 11:31:04 -0000, "BartC" <(E-Mail Removed)> wrote:

>Also, nvram_init() appears to be called recursively, which is unusual for
>this sort of function. Probably not the cause of this bug, but I can see
>subtle problems creeping in because each different invocation of
>nvram_init() is modifying the same static variable.


Not recursive. It's calling some kind of internal, implementation
defined _nvram_init() as suggested by the underscore. This code is
meant to be embedded and I'd be surprised if anyone can come up with a
scenario that can duplicate his problem. The code by itself doesn't
suggest where his 0 is coming from and certainly nothing is visible
between the initialization of nvram_status and his printf statement.

The unused bool isemb variable also suggests he's got a lot of hidden
things going on inside his target platform that he hasn't disclosed.
 
Reply With Quote
 
Mark
Guest
Posts: n/a
 
      12-29-2010
Francois Grieu wrote:
> In some embedded environments, initialization of static and global
> variables can be disabled or enabled depending on linking options
> or input. One good reason is to be able to perform things quickly
> enough before main() [hardware setup, RAM test, unamit]. Sometime,
> this initialization is replaced or superseded by a "zero all RAM"
> procedure. That would explain the behavior.


The reason for the "strange behaviour" was a trivial one as expected,
'nvram_init' was called in the very *early* stage of the firmware
initialization, the place I've missed to check (silly me), and that altered
'nvram_status' to zero as indication that NVRAM partition presents in the
system.

Thanks for some valuable insights.

--
Mark

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Thunderbird strange behavior... Jim Firefox 5 11-17-2005 03:09 PM
Firefox 1.04 and Strange Find Behavior Thomas Firefox 5 06-28-2005 08:40 PM
utf8 pragma - strange behavior ryang Perl 1 04-11-2005 05:38 AM
strange behavior when using 'read' sstark Perl 0 03-06-2005 02:27 AM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM



Advertisments