Write only memory

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jacob navia

    Write only memory

    In C, we have read-only memory (const), read/write memory
    (normal data), and write only memory.

    Let's look at the third one in more detail.

    Write only memory is a piece of RAM that can only
    be written to, since its contents are undefined.

    The program is allocating a new piece of data, and
    the previous contents aren't relevant. This memory
    is generated by malloc and friends, or allocated
    statically by the compiler by making the processor
    increase the stack area at the entry of the function.

    When you read from write only memory (you use an
    uninitialized variable) the behavior is undefined,
    i.e. it is declared a big mistake.

    It is big because the consequences are random. When
    a value is read from that memory locations, its contents
    are random. We know that if we have rebooted maybe the
    OS has just cleaned up and this memory is not quite
    random, it is mostly zero. If the machine is running
    since a while however, the contents are probably
    whatever data was written to that address before, in
    another program.

    The symptoms are very vague. Programs that run at the
    start stop working, a program that has just run crashes,
    symptoms that *could* be related to this program or not.

    Confusing symptoms.

    This confusion is because of the random nature of the
    data being introduced in the program.

    The great remedy of course, is to have default values
    for all local variables and set them at the start. This
    doesn't eliminate all bugs, but at least
    eliminates those of reading from write only memory.

    As a first approach:
    Data *Function(Data *d, index i)
    {
    Data workCopy;
    DataIndex di;
    etc...

    memset(&workCop y,0,sizeof(Data ));
    memset(&di, 0, sizeof(DataInde x));
    etc...
    }

    Shorter would be:
    Data *Function(Data *d, index i)
    {
    Data workCopy={0};
    DataIndex di={0};
    etc...

    }

    This already much better, but it is still bothersome
    if you forget one.

    Even better would be if we would just write:

    _Pragma(Stdc,Ze roinit,Function )

    meaning that in the given function all local
    data should be zeroed before use at function
    entry.

    But that is still too long...

    Couldn't we just decide that by default all locals
    are zeroed at entry of the function?

    Only when you write:

    _Pragma(Stdc, Nozeroinit, function)

    would be the zeroing of memory be avoided.

    I think that would be the best. Not to write
    anything at all. This would slow software a bit,
    (maybe) but for *many* applications running
    in PCs today that would not do any real
    performance lost.

    Zero is used as default value in many situations,
    pointers couldn't by chance destroy another data item
    since even uninitialized pointers would be NULL.

    How nice. This would mean also no change to
    existing programs. They would just run a few
    microseconds slower and nobody would care.

    The data must be brought to the L1 cache anyway,
    and zeroing locals ensures that they do not
    provoke a processor L1 cache fault later within
    the code of the function. A burst mode
    can be probably used if present. This reduces
    the cost of each cache failure: all at once.

    Most locals space is small anyway.

    The problems arising from reading write-only
    memory would be restricted to hard traps in
    the program, very easy to pinpoint to a
    specific line of code.

    In most implementations a NULL dereference
    traps, and the error is pinpointed exactly
    where it arises. With bogus values in a
    pointer there is some chance that the pointer
    destroys other data structures. Using NULL
    there is none. The integrity of the program itself
    is not destroyed.
  • Chris Barts

    #2
    Re: Write only memory

    On Thu, 14 Oct 2004 23:32:05 +0200, jacob navia wrote:
    [color=blue]
    > In C, we have read-only memory (const), read/write memory
    > (normal data), and write only memory.
    >
    > Let's look at the third one in more detail.
    >
    > Write only memory is a piece of RAM that can only
    > be written to, since its contents are undefined.[/color]

    Funny... I thought write-only memory was /dev/null.

    (Or the programmer after a couple beers. ;-))
    [color=blue]
    >
    > The program is allocating a new piece of data, and
    > the previous contents aren't relevant. This memory
    > is generated by malloc and friends, or allocated
    > statically by the compiler by making the processor
    > increase the stack area at the entry of the function.[/color]

    Or however the compiler and hardware like to do it. But this is
    irrelevant.
    [color=blue]
    >
    > When you read from write only memory (you use an
    > uninitialized variable) the behavior is undefined,
    > i.e. it is declared a big mistake.
    >
    > It is big because the consequences are random. When
    > a value is read from that memory locations, its contents
    > are random. We know that if we have rebooted maybe the
    > OS has just cleaned up and this memory is not quite
    > random, it is mostly zero. If the machine is running
    > since a while however, the contents are probably
    > whatever data was written to that address before, in
    > another program.
    >
    > The symptoms are very vague. Programs that run at the
    > start stop working, a program that has just run crashes,
    > symptoms that *could* be related to this program or not.
    >
    > Confusing symptoms.
    >
    > This confusion is because of the random nature of the
    > data being introduced in the program.
    >
    > The great remedy of course, is to have default values
    > for all local variables and set them at the start. This
    > doesn't eliminate all bugs, but at least
    > eliminates those of reading from write only memory.[/color]

    Yes, this is why some debuggers will initialize memory of this sort to a
    known but unusual value, to turn Heisenbugs of this kind into Bohr bugs.
    0xDEADBEEF and 0xCAFEBABE are common on 32-bit systems which have
    debuggers with this function.

    [bobbit]
    [color=blue]
    > This already much better, but it is still bothersome
    > if you forget one.
    >
    > Even better would be if we would just write:
    >
    > _Pragma(Stdc,Ze roinit,Function )
    >
    > meaning that in the given function all local
    > data should be zeroed before use at function
    > entry.[/color]

    I think all pragmas look like preprocessor directives. That is, it should
    be written as:

    #pragma (...)
    [color=blue]
    >
    > But that is still too long...[/color]

    Not for me. Not if I want my compiled code to not waste its time zeroing
    RAM I'll never accidentally access, because I enforce a modicum of hygiene
    on my code.
    [color=blue]
    >
    > Couldn't we just decide that by default all locals
    > are zeroed at entry of the function?[/color]

    This loses when a function needs to declare really large locals and the
    programmer is smart enough to not access them before they've been written
    to. Your CPU burns clock cycles and expensive RAM access time for no good
    reason.
    [color=blue]
    >
    > Only when you write:
    >
    > _Pragma(Stdc, Nozeroinit, function)
    >
    > would be the zeroing of memory be avoided.[/color]

    /This/ is too much typing.
    [color=blue]
    >
    > I think that would be the best. Not to write
    > anything at all. This would slow software a bit,
    > (maybe) but for *many* applications running
    > in PCs today that would not do any real
    > performance lost.[/color]

    Bah. C isn't (just) for PCs. C is for embedded devices and
    high-performance systems that don't want to waste time looking out for
    incompetent programmers.
    [color=blue]
    >
    > Zero is used as default value in many situations,
    > pointers couldn't by chance destroy another data item
    > since even uninitialized pointers would be NULL.[/color]

    No. Wrong. NULL != 0x00000000 on all systems. Programmers who think it is
    get bitten.
    [color=blue]
    >
    > How nice. This would mean also no change to
    > existing programs. They would just run a few
    > microseconds slower and nobody would care.[/color]

    Wrong. Programs controlling things like heart-lung machines and
    supercomputers could run noticeably slower, and this is not always
    acceptable.
    [color=blue]
    >
    > The data must be brought to the L1 cache anyway,
    > and zeroing locals ensures that they do not
    > provoke a processor L1 cache fault later within
    > the code of the function. A burst mode
    > can be probably used if present. This reduces
    > the cost of each cache failure: all at once.[/color]

    "The fool in his heart thinks `All the world's a PC.'"
    [color=blue]
    >
    > Most locals space is small anyway.[/color]

    Not always. It may be quite large if the function is doing lots of vector
    or matrix math, as in graphical applications.
    [color=blue]
    >
    > The problems arising from reading write-only
    > memory would be restricted to hard traps in
    > the program, very easy to pinpoint to a
    > specific line of code.[/color]

    This is why you have a debugger. (This is also why you have eyes and a
    brain, but apparently those cannot be safely assumed anymore.)
    [color=blue]
    >
    > In most implementations a NULL dereference
    > traps, and the error is pinpointed exactly
    > where it arises. With bogus values in a
    > pointer there is some chance that the pointer
    > destroys other data structures. Using NULL
    > there is none. The integrity of the program itself
    > is not destroyed.[/color]

    This loses on systems without an MMU, and an embedded system usually does
    not need an MMU. Again, thinking the world is a PC is pretty stupid.

    Comment

    • Lamb9bert

      #3
      Re: Write only memory

      >This loses when a function needs to declare really large locals and the[color=blue]
      >programmer is smart enough to not access them before they've been written
      >to. Your CPU burns clock cycles and expensive RAM access time for no good
      >reason.
      >[/color]

      Not to mention that a lot of errors come from wrong uses of malloc(). Of
      course this is a lot like calloc()...

      --
      (anonymous)

      Comment

      • Chris Barts

        #4
        Re: Write only memory

        Lamb9bert wrote:[color=blue][color=green]
        >>This loses when a function needs to declare really large locals and the
        >>programmer is smart enough to not access them before they've been written
        >>to. Your CPU burns clock cycles and expensive RAM access time for no good
        >>reason.
        >>[/color]
        >
        >
        > Not to mention that a lot of errors come from wrong uses of malloc(). Of
        > course this is a lot like calloc()...[/color]

        Hopefully, two things are true:

        1. calloc() is implemented intelligently at the machine-code level, and
        so can do a very fast zeroing of core because it always knows precisely
        how much core it needs to wipe. A compiler, at least one that implements
        VLAs, doesn't always know this.

        2. The programmer doesn't use calloc() without good reason. The
        programmer /especially/ doesn't use calloc() because he thinks it will
        NULL an array of pointers. (This is in the FAQ, I think.)

        Of course, the first one is QoI, and the second one is QoP. ;)

        Comment

        • jacob navia

          #5
          Re: Write only memory

          Chris Barts wrote:[color=blue][color=green]
          >>The great remedy of course, is to have default values
          >>for all local variables and set them at the start. This
          >>doesn't eliminate all bugs, but at least
          >>eliminates those of reading from write only memory.[/color]
          >
          >
          > Yes, this is why some debuggers will initialize memory of this sort to a
          > known but unusual value, to turn Heisenbugs of this kind into Bohr bugs.
          > 0xDEADBEEF and 0xCAFEBABE are common on 32-bit systems which have
          > debuggers with this function.
          >[/color]

          lcc-win32 uses 0xFFFA5A5A
          [color=blue]
          > [bobbit]
          >
          >[color=green]
          >>This already much better, but it is still bothersome
          >>if you forget one.
          >>
          >>Even better would be if we would just write:
          >>
          >>_Pragma(Stdc, Zeroinit,Functi on)
          >>
          >>meaning that in the given function all local
          >>data should be zeroed before use at function
          >>entry.[/color]
          >
          >
          > I think all pragmas look like preprocessor directives. That is, it should
          > be written as:
          >
          > #pragma (...)
          >[/color]
          C99 makes _Pragma and #pragma equivalent[color=blue]
          >[color=green]
          >>But that is still too long...[/color]
          >
          >
          > Not for me. Not if I want my compiled code to not waste its time zeroing
          > RAM I'll never accidentally access, because I enforce a modicum of hygiene
          > on my code.
          >
          >[color=green]
          >>Couldn't we just decide that by default all locals
          >>are zeroed at entry of the function?[/color]
          >
          >
          > This loses when a function needs to declare really large locals and the
          > programmer is smart enough to not access them before they've been written
          > to. Your CPU burns clock cycles and expensive RAM access time for no good
          > reason.
          >
          >[color=green]
          >>Only when you write:
          >>
          >>_Pragma(Std c, Nozeroinit, function)
          >>
          >>would be the zeroing of memory be avoided.[/color]
          >
          >
          > /This/ is too much typing.
          >[/color]
          This could be replaced with a compile time switch that would be global
          [color=blue]
          >[color=green]
          >>I think that would be the best. Not to write
          >>anything at all. This would slow software a bit,
          >>(maybe) but for *many* applications running
          >>in PCs today that would not do any real
          >>performance lost.[/color]
          >
          >
          > Bah. C isn't (just) for PCs. C is for embedded devices and
          > high-performance systems that don't want to waste time looking out for
          > incompetent programmers.
          >[/color]

          Even the best programmers do make mistakes.
          Of course it never happens to you...
          [color=blue]
          >[color=green]
          >>How nice. This would mean also no change to
          >>existing programs. They would just run a few
          >>microsecond s slower and nobody would care.[/color]
          >
          >
          > Wrong. Programs controlling things like heart-lung machines and
          > supercomputers could run noticeably slower, and this is not always
          > acceptable.
          >[/color]

          Mmm I would prefer a heart-lung machine with no bugs
          pleeeeeeeeeeeze ...

          This "speed at any price" attitude is widespred. Todays
          embedded systems use CPUs that leave PCs behind. The
          Analog Devices DSPs are 32 bit for instance, and feature
          an impresive speed, very comparable to PCs.
          [color=blue]
          >[color=green]
          >>The data must be brought to the L1 cache anyway,
          >>and zeroing locals ensures that they do not
          >>provoke a processor L1 cache fault later within
          >>the code of the function. A burst mode
          >>can be probably used if present. This reduces
          >>the cost of each cache failure: all at once.[/color]
          >
          >
          > "The fool in his heart thinks `All the world's a PC.'"
          >[/color]

          Very few modern processor do not have a cache. Yes,
          I know that there are other things that PCs but I am
          speaking about a PC environment.

          This whole discussion brings us to several possible
          modes of execution in C.

          You would have a SAFE mode with many kinds of checks,
          and a FAST mode, where those checks would be normally
          disabled.

          There is no "one fits all" solution, and splitting the
          run time into several would be better.

          Speed is only one of the factors in software. There are
          many others like security, robustness, etc, that in
          many applications are more important than "speed".

          Comment

          • Mark F. Haigh

            #6
            Re: Write only memory

            jacob navia wrote:[color=blue]
            > In C, we have read-only memory (const), read/write memory
            > (normal data), and write only memory.
            >
            > Let's look at the third one in more detail.
            >
            > Write only memory is a piece of RAM that can only
            > be written to, since its contents are undefined.[/color]

            Make that 'should only be written to'. There's no reason you can't use
            unsigned chars to access the location and print what you find there.
            [color=blue]
            >
            > The program is allocating a new piece of data, and
            > the previous contents aren't relevant. This memory
            > is generated by malloc and friends, or allocated
            > statically by the compiler by making the processor
            > increase the stack area at the entry of the function.
            >
            > When you read from write only memory (you use an
            > uninitialized variable) the behavior is undefined,
            > i.e. it is declared a big mistake.
            >
            > It is big because the consequences are random. When
            > a value is read from that memory locations, its contents
            > are random.[/color]

            Many compilers do a decent job at data flow analysis and catch the
            obvious uses of uninitialized memory. There are both commercial and
            free static data analysis tools (splint, pc-lint, etc), as well as
            runtime analysis tools (valgrind, purify, etc) you can use.
            Additionally, some debug runtimes initialize uninitialized memory with
            sentinel values to aid debugging.
            [color=blue]
            > We know that if we have rebooted maybe the
            > OS has just cleaned up and this memory is not quite
            > random, it is mostly zero. If the machine is running
            > since a while however, the contents are probably
            > whatever data was written to that address before, in
            > another program.
            >
            > The symptoms are very vague. Programs that run at the
            > start stop working, a program that has just run crashes,
            > symptoms that *could* be related to this program or not.[/color]

            Not usually these days, unless you're running on an embedded system (or
            a legacy OS). Because of security implications, all protected mode
            operating systems I know of only supply zero-filled pages to user
            processes. Usually this is done with a kernel thread that executes as
            part of the idle loop.

            Within a process, sure, you'll get re-used pages, but this is only
            within a process' lifetime, and really has nothing to do with whether or
            not the machine has been running for a while or has just been rebooted.
            [color=blue]
            >
            > Confusing symptoms.
            >
            > This confusion is because of the random nature of the
            > data being introduced in the program.
            >
            > The great remedy of course, is to have default values
            > for all local variables and set them at the start. This
            > doesn't eliminate all bugs, but at least
            > eliminates those of reading from write only memory.[/color]

            And this is certainly enforcable with static analysis tools, if that's
            your cup of tea. No need to get fancy.
            [color=blue]
            >
            > As a first approach:
            > Data *Function(Data *d, index i)
            > {
            > Data workCopy;
            > DataIndex di;
            > etc...
            >
            > memset(&workCop y,0,sizeof(Data ));
            > memset(&di, 0, sizeof(DataInde x));
            > etc...
            > }
            >
            > Shorter would be:
            > Data *Function(Data *d, index i)
            > {
            > Data workCopy={0};
            > DataIndex di={0};
            > etc...
            >
            > }
            >
            > This already much better, but it is still bothersome
            > if you forget one.
            >
            > Even better would be if we would just write:
            >
            > _Pragma(Stdc,Ze roinit,Function )[/color]

            I don't think it's better.
            [color=blue]
            >
            > meaning that in the given function all local
            > data should be zeroed before use at function
            > entry.
            >
            > But that is still too long...
            >
            > Couldn't we just decide that by default all locals
            > are zeroed at entry of the function?
            >
            > Only when you write:
            >
            > _Pragma(Stdc, Nozeroinit, function)
            >
            > would be the zeroing of memory be avoided.[/color]

            Once again, not better.
            [color=blue]
            >
            > I think that would be the best. Not to write
            > anything at all. This would slow software a bit,
            > (maybe) but for *many* applications running
            > in PCs today that would not do any real
            > performance lost.[/color]

            C is mostly used where the impact would be higher than you expect. I
            don't want my python and perl interpreters compiled with this. I don't
            want my device drivers compiled with this.

            In the embedded systems I work on, I don't want anything like this.
            Especially in the more resource-constrained ones, which, believe it or
            not, are becoming more and more prevalent.
            [color=blue]
            >
            > Zero is used as default value in many situations,
            > pointers couldn't by chance destroy another data item
            > since even uninitialized pointers would be NULL.
            >
            > How nice. This would mean also no change to
            > existing programs. They would just run a few
            > microseconds slower and nobody would care.[/color]

            Unless said system does not have a MMU and you blast away the interrupt
            vector table or something else important. Not to mention that NULL does
            not necessarily mean 'all bits zero'.
            [color=blue]
            >
            > The data must be brought to the L1 cache anyway,
            > and zeroing locals ensures that they do not
            > provoke a processor L1 cache fault later within
            > the code of the function. A burst mode
            > can be probably used if present. This reduces
            > the cost of each cache failure: all at once.[/color]

            What? L1's come in a variety of shapes and sizes, if there's one at
            all. And why pay up front for branches you might not take, for storage
            you might not use. It doesn't make sense. It introduces cache pressure
            and potentially causes problems where writes block reads and the write
            buffer isn't deep.
            [color=blue]
            >
            > Most locals space is small anyway.[/color]

            Yeah, sure.
            [color=blue]
            >
            > The problems arising from reading write-only
            > memory would be restricted to hard traps in
            > the program, very easy to pinpoint to a
            > specific line of code.[/color]

            So tell me, how do you get there from here? Now you're talking about
            data type trap representations . Some types are guaranteed not to have
            trap representations . If I read from an uninitialized unsigned char
            type, I cannot possibly cause the program to trap.
            [color=blue]
            >
            > In most implementations a NULL dereference
            > traps, and the error is pinpointed exactly
            > where it arises. With bogus values in a
            > pointer there is some chance that the pointer
            > destroys other data structures. Using NULL
            > there is none. The integrity of the program itself
            > is not destroyed.[/color]

            Whatever. The integrity of a program chasing around random pointers is
            not likely to be saved despite your best intentions.


            Mark F. Haigh
            mfhaigh@sbcglob al.net

            Comment

            • Mark F. Haigh

              #7
              Re: Write only memory

              jacob navia wrote:


              <snip>
              [color=blue]
              > lcc-win32 uses 0xFFFA5A5A[/color]

              That's fantastic.

              <snip>
              [color=blue]
              >
              > This "speed at any price" attitude is widespred. Todays
              > embedded systems use CPUs that leave PCs behind. The
              > Analog Devices DSPs are 32 bit for instance, and feature
              > an impresive speed, very comparable to PCs.
              >[/color]

              Go do your homework, son-- you obviously don't have a clue. Or are you
              one of ERT's alter-egos?



              Mark F. Haigh
              mfhaigh@sbcglob al.net

              Comment

              • CBFalconer

                #8
                Re: Write only memory

                jacob navia wrote:[color=blue]
                >
                > In C, we have read-only memory (const), read/write memory
                > (normal data), and write only memory.
                >
                > Let's look at the third one in more detail.
                >
                > Write only memory is a piece of RAM that can only be written to[/color]
                .... snip ...

                Many moons ago, when Sylvania still made memory chips, they
                produced such a device and supplied a data sheet for it. You might
                find it on the web somewhere.

                --
                Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                Available for consulting/temporary embedded and systems.
                <http://cbfalconer.home .att.net> USE worldnet address!


                Comment

                • Chris Barts

                  #9
                  Re: Write only memory

                  -----BEGIN PGP SIGNED MESSAGE-----
                  Hash: SHA1

                  jacob navia wrote:
                  | Chris Barts wrote:
                  |
                  |> jacob navia wrote:
                  |>> Even better would be if we would just write:
                  |>>
                  |>> _Pragma(Stdc,Ze roinit,Function )
                  |>>
                  |>> meaning that in the given function all local
                  |>> data should be zeroed before use at function
                  |>> entry.
                  |>
                  |>
                  |>
                  |> I think all pragmas look like preprocessor directives. That is, it should
                  |> be written as:
                  |>
                  |> #pragma (...)
                  |>
                  | C99 makes _Pragma and #pragma equivalent

                  I did not know that.

                  |>> Only when you write:
                  |>>
                  |>> _Pragma(Stdc, Nozeroinit, function)
                  |>>
                  |>> would be the zeroing of memory be avoided.
                  |>
                  |>
                  |>
                  |> /This/ is too much typing.
                  |>
                  | This could be replaced with a compile time switch that would be global

                  Then conformant programs could have wildly variant behaviors depending
                  on something fully outside the source code. I think a Standardized
                  language should minimize things like that.

                  |
                  |>
                  |>> I think that would be the best. Not to write
                  |>> anything at all. This would slow software a bit,
                  |>> (maybe) but for *many* applications running
                  |>> in PCs today that would not do any real
                  |>> performance lost.
                  |>
                  |>
                  |>
                  |> Bah. C isn't (just) for PCs. C is for embedded devices and
                  |> high-performance systems that don't want to waste time looking out for
                  |> incompetent programmers.
                  |>
                  |
                  | Even the best programmers do make mistakes.
                  | Of course it never happens to you...

                  I have never made this kind of error, no. I do, of course, make
                  mistakes, but I don't expect the compiler to hold my hand. I have a very
                  nice debugger to step through my code, and I have a nicer brain to
                  reason things through.

                  |
                  |>
                  |>> How nice. This would mean also no change to
                  |>> existing programs. They would just run a few
                  |>> microseconds slower and nobody would care.
                  |>
                  |>
                  |>
                  |> Wrong. Programs controlling things like heart-lung machines and
                  |> supercomputers could run noticeably slower, and this is not always
                  |> acceptable.
                  |>
                  |
                  | Mmm I would prefer a heart-lung machine with no bugs
                  | pleeeeeeeeeeeze ...

                  How about a heart-lung machine that always works fast enough to keep
                  your heart and/or lungs going? And is still cheap enough for your
                  hospital to afford?

                  Plus, your scheme will not catch many, or even most, bugs. Programmers
                  writing software for essential systems should be experienced enough to
                  not need your proposed modifications.

                  |
                  | This "speed at any price" attitude is widespred. Todays
                  | embedded systems use CPUs that leave PCs behind. The
                  | Analog Devices DSPs are 32 bit for instance, and feature
                  | an impresive speed, very comparable to PCs.

                  Uh, what? Embedded systems are more cost-conscious than PCs, and they
                  are usually more heat- and power-conscious as well. (Speed usually ups
                  both power consumption and heat production, something that is often
                  unacceptable in embedded systems.)

                  And DSPs are something completely different.

                  |>
                  |> "The fool in his heart thinks `All the world's a PC.'"
                  |>
                  |
                  | Very few modern processor do not have a cache. Yes,
                  | I know that there are other things that PCs but I am
                  | speaking about a PC environment.

                  And here, again, you prove that you should /not/ be proposing
                  modifications to Standard C. C is widely used in non-PC environments,
                  non-workstation environments, and even non-hosted environments. /All/
                  modifications to Standard C must be reviewed with that firmly in mind.

                  [snip]

                  | Speed is only one of the factors in software. There are
                  | many others like security, robustness, etc, that in
                  | many applications are more important than "speed".

                  This is perhaps the only intelligent comment you've had so far.
                  -----BEGIN PGP SIGNATURE-----
                  Version: GnuPG v1.2.6 (GNU/Linux)
                  Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

                  iD8DBQFBb5uQBsE yCHtFPhsRAmegAJ 9wW9Ugnq8Eb8VM9 MkonRX17g2QFQCe P2Pu
                  2PO/fPsjuajy1VCqX9d 1knA=
                  =3hcm
                  -----END PGP SIGNATURE-----

                  Comment

                  • Keith Thompson

                    #10
                    Re: Write only memory

                    jacob navia <jacob@jacob.re mcomp.fr> writes:[color=blue]
                    > In C, we have read-only memory (const), read/write memory
                    > (normal data), and write only memory.
                    >
                    > Let's look at the third one in more detail.
                    >
                    > Write only memory is a piece of RAM that can only
                    > be written to, since its contents are undefined.[/color]

                    I find your terminology confusing and misleading.

                    Read-only memory is memory that can only be read, not written. (How
                    and whether this is enforced is another question.)

                    Read/write memory is memory that can be either read or written;
                    presumably reading gives you the last value written to it.

                    In both cases, the memory remains read-only or read/write
                    indefinitely, regardless of what you do with it.

                    What you call "write only memory" is memory that *should* not be read
                    because it hasn't been initialized. Once you initialize it, it
                    becomes read/write memory. Calling it write-only implies a concept
                    analagous to read-only and read/write.

                    Just call it what it is: uninitialized memory.

                    --
                    Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                    We must do something. This is something. Therefore, we must do this.

                    Comment

                    • Mark McIntyre

                      #11
                      Re: Write only memory

                      On Thu, 14 Oct 2004 23:32:05 +0200, in comp.lang.c , jacob navia
                      <jacob@jacob.re mcomp.fr> wrote:
                      [color=blue]
                      >In C, we have read-only memory (const), read/write memory
                      >(normal data), and write only memory.[/color]

                      The last doesn't exist.
                      [color=blue]
                      >Let's look at the third one in more detail.[/color]

                      Tricky, since it doesn't exist.
                      [color=blue]
                      >Write only memory is a piece of RAM that can only
                      >be written to, since its contents are undefined.[/color]

                      No, thats read/write memory that you've not yet initialised. Different
                      animal.

                      Your definition of write-only is asymmetric with your definition of
                      read-only, which is a nono. (I'm assuming you mean constants by that. If
                      not, then you have no argument at all.

                      --
                      Mark McIntyre
                      CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
                      CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt >


                      ----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
                      http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
                      ---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---

                      Comment

                      • Peter Shaggy Haywood

                        #12
                        Re: Write only memory

                        Groovy hepcat jacob navia was jivin' on Thu, 14 Oct 2004 23:32:05
                        +0200 in comp.lang.c.
                        Write only memory's a cool scene! Dig it!
                        [color=blue]
                        >In C, we have read-only memory (const), read/write memory
                        >(normal data), and write only memory.[/color]

                        Nonsense! In C we have const qualified objects and objects that are
                        not const qualified. We have objects that are modifiable and objects
                        (such as string literals) which, whether const qualified or not, may
                        not be modifiable. There is no such thing as "write only memory".
                        [color=blue]
                        >Let's look at the third one in more detail.
                        >
                        >Write only memory is a piece of RAM that can only
                        >be written to, since its contents are undefined.[/color]

                        Piffle!
                        [color=blue]
                        >The program is allocating a new piece of data, and
                        >the previous contents aren't relevant. This memory
                        >is generated by malloc and friends, or allocated
                        >statically by the compiler by making the processor
                        >increase the stack area at the entry of the function.[/color]

                        Complete and utter nonsense! There ain't no sech animal as a stack
                        in the C language. And memory allocated by malloc() can be read. It
                        just causes undefined behaviour if you do so before putting useful
                        values into it first. The same goes for any object, not just
                        dynamically allocated ones.
                        [color=blue]
                        >When you read from write only memory (you use an
                        >uninitialize d variable) the behavior is undefined,
                        >i.e. it is declared a big mistake.
                        >
                        >It is big because the consequences are random. When
                        >a value is read from that memory locations, its contents
                        >are random. We know that if we have rebooted maybe the
                        >OS has just cleaned up and this memory is not quite
                        >random, it is mostly zero. If the machine is running
                        >since a while however, the contents are probably
                        >whatever data was written to that address before, in
                        >another program.
                        >
                        >The symptoms are very vague. Programs that run at the
                        >start stop working, a program that has just run crashes,
                        >symptoms that *could* be related to this program or not.[/color]

                        Do you know of any implementation which displays such simptoms as a
                        result of reading an uninitialised object? The most common symptom is
                        spurious values being displayed by the program (based on reading
                        spurious values from uninitialised objects).
                        [color=blue]
                        >Confusing symptoms.
                        >
                        >This confusion is because of the random nature of the
                        >data being introduced in the program.
                        >
                        >The great remedy of course, is to have default values
                        >for all local variables and set them at the start. This[/color]

                        This is not always necessary. Some people like to do that, but not
                        everyone.
                        [color=blue]
                        >doesn't eliminate all bugs, but at least
                        >eliminates those of reading from write only memory.[/color]

                        No such thing!
                        [color=blue]
                        >As a first approach:
                        >Data *Function(Data *d, index i)
                        >{
                        > Data workCopy;
                        > DataIndex di;
                        > etc...
                        >
                        > memset(&workCop y,0,sizeof(Data ));
                        > memset(&di, 0, sizeof(DataInde x));
                        > etc...
                        >}
                        >
                        >Shorter would be:
                        >Data *Function(Data *d, index i)
                        >{
                        > Data workCopy={0};
                        > DataIndex di={0};
                        > etc...
                        >}
                        >
                        >This already much better, but it is still bothersome
                        >if you forget one.
                        >
                        >Even better would be if we would just write:
                        >
                        >_Pragma(Stdc,Z eroinit,Functio n)
                        >
                        >meaning that in the given function all local
                        >data should be zeroed before use at function
                        >entry.
                        >
                        >But that is still too long...
                        >
                        >Couldn't we just decide that by default all locals
                        >are zeroed at entry of the function?[/color]

                        No, we couldn't. The C language does not require it, and it may slow
                        some programs down.
                        [color=blue]
                        >Only when you write:
                        >
                        >_Pragma(Stdc , Nozeroinit, function)
                        >
                        >would be the zeroing of memory be avoided.
                        >
                        >I think that would be the best. Not to write
                        >anything at all. This would slow software a bit,
                        >(maybe) but for *many* applications running
                        >in PCs today that would not do any real
                        >performance lost.
                        >
                        >Zero is used as default value in many situations,
                        >pointers couldn't by chance destroy another data item
                        >since even uninitialized pointers would be NULL.
                        >
                        >How nice. This would mean also no change to
                        >existing programs. They would just run a few
                        >microseconds slower and nobody would care.
                        >
                        >The data must be brought to the L1 cache anyway,[/color]

                        Nonsense! The C language does not define "L1 cache".
                        [color=blue]
                        >and zeroing locals ensures that they do not
                        >provoke a processor L1 cache fault later within
                        >the code of the function. A burst mode[/color]

                        The C language does not define "burst mode".
                        [color=blue]
                        >can be probably used if present. This reduces
                        >the cost of each cache failure: all at once.
                        >
                        >Most locals space is small anyway.
                        >
                        >The problems arising from reading write-only
                        >memory would be restricted to hard traps in
                        >the program, very easy to pinpoint to a
                        >specific line of code.
                        >
                        >In most implementations a NULL dereference
                        >traps, and the error is pinpointed exactly
                        >where it arises. With bogus values in a
                        >pointer there is some chance that the pointer
                        >destroys other data structures. Using NULL
                        >there is none. The integrity of the program itself
                        >is not destroyed.[/color]

                        And what is the point of all this tripe?

                        --

                        Dig the even newer still, yet more improved, sig!


                        "Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
                        I know it's not "technicall y correct" English; but since when was rock & roll "technicall y correct"?

                        Comment

                        • pete

                          #13
                          Re: Write only memory

                          jacob navia wrote:
                          [color=blue]
                          > When you read from write only memory (you use an
                          > uninitialized variable) the behavior is undefined,
                          > i.e. it is declared a big mistake.[/color]

                          The last time that I discussed this on comp.std.c,
                          they told me that an object with an indeterminate value,
                          such as a freed pointer or even an uninitialized object,
                          could be read as an array of unsigned char.

                          --
                          pete

                          Comment

                          • pete

                            #14
                            Re: Write only memory

                            pete wrote:[color=blue]
                            >
                            > jacob navia wrote:
                            >[color=green]
                            > > When you read from write only memory (you use an
                            > > uninitialized variable) the behavior is undefined,
                            > > i.e. it is declared a big mistake.[/color]
                            >
                            > The last time that I discussed this on comp.std.c,
                            > they told me that an object with an indeterminate value,
                            > such as a freed pointer or even an uninitialized object,
                            > could be read as an array of unsigned char.[/color]

                            A kind of memory that changes it's status after a write,
                            is not consistent with what
                            "read-only memory (const), read/write memory"
                            means.

                            What you've done by coining "write only" is that you have attempted
                            to classify memory based on whether it has an indeterminate
                            value according to the object's declared type, and you've got it wrong.

                            --
                            pete

                            Comment

                            • CBFalconer

                              #15
                              Re: Write only memory

                              Peter Shaggy Haywood wrote:[color=blue]
                              > Groovy hepcat jacob navia was jivin'
                              >[/color]
                              .... snip ...[color=blue][color=green]
                              >>
                              >> In most implementations a NULL dereference
                              >> traps, and the error is pinpointed exactly
                              >> where it arises. With bogus values in a
                              >> pointer there is some chance that the pointer
                              >> destroys other data structures. Using NULL
                              >> there is none. The integrity of the program itself
                              >> is not destroyed.[/color]
                              >
                              > And what is the point of all this tripe?[/color]

                              I originally thought he was making a joke and didn't bother reading
                              it. From the portion you quoted it appears he was actually
                              serious! He is proposing YANCIC [1] in the wrong forum.

                              [1] Yet another Navian change in C.

                              --
                              "I support the Red Sox and any team that beats the Yankees"

                              "Any baby snookums can be a Yankee fan, it takes real moral
                              fiber to be a Red Sox fan"


                              Comment

                              Working...