Announcement

Collapse

New Sub-Forum

In an effort to help make sure there are appropriate categories for topics of discussion that are happening, there is now a sub-forum for databases and database programming under Special Interest groups. Please direct questions, etc., about this topic to that sub-forum moving forward. Thank you.
See more
See less

Memory corruption 101 ?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Memory corruption 101 ?

    We know that strange problems may occur when our program corrupts memory in some way. Late side effects, hard-to-track crashes, problems with the debugger etc.

    However I don't think there is a clear common understanding of how memory corruption may occur. That's still actually understood just by some people. I hope some of them can help to build some shallow but clear understanding of this matter.

    For example, corrupting memory by referencing an array out of its bounds, ok, but would this always set ERR to 9 if we have #DEBUG ERROR ON ? Same concept for bad pointers. That'd tell us that checking ERR properly would help a lot to avoid corrupting memory.

    So a general question might be (ASM aside): is it possible that memory gets corrupted even though ERR always stayed = 0 ? If yes, what's an example of how this can be done ? (to avoid doing it of course ).

    Another example of questions useful to get a better understanding: is it possible that another running program comes to corrupt the memory of our program ? Wouldn't this cause an immediate GPF by the OS ?

    Another possible point: is there some way of "checking whether the memory is currently corrupted" ? That'd be useful code to throw in to debug these problems.

  • #2
    There are many ways memory can get corrupted. Array out of bounds is just one way, and is probably the easiest to solve as PB can detect it and generate an error code. I find the two most common reasons are:

    1) Overwriting global memory that you didn't allocate. ie. allocate 100 bytes with String$ or GlobalAlloc, and writing over 100 bytes to the allocated pointer. This will cause the most damage as the memory directly after your allocated block could be in use by another allocation, so that memory is corrupted.

    2) Using a bad pointer to start with. It is easy in larger apps to reference a pointer that has been freed or (if using arithmetic with it), a pointer that simply is out of scope to what you allocated. Freed pointer problems are hard to track down as usually the data is still there, but will be overwritten by Windows later, causing untold problems. Also, attempting to write to the freed pointer could be disastrous (see point 1)

    Obviously, if you have a program that crashes, you would first want to run it through the debugger to check for any problems with the PB code, which will normally flag an ERR value. If this doesn't help, go over any areas which use pointers and check that the pointer is valid (in scope) and you are not reading/writing past it's allocated size (see API functions IsReadPtr/IsWritePtr). It's also probably best to use a console or msgbox to spit out debug info when you are testing. You'll find that placing "markers" around in the code will help to narrow down exactly where the GPF occurs.

    In 32-bit Windows I don't think it's possible for another application (process) to corrupt your programs memory. Unless it is a hacking tool or other malicious code.

    Hope this was of some help
    Last edited by Kev Peel; 28 Oct 2007, 02:43 PM.
    kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

    Comment


    • #3
      Thanks Kev,

      the IsBadReadPtr/IsBadWritePtr is a great hint; I'll use that before accessing pointers in the sections of code under examination. I think ERR in my case stays always 0, I check it all the time, so I hope it's just bad pointers, and these APIs might help me find it.

      Comment


      • #4
        Originally posted by Kev Peel View Post
        Hope this was of some help
        It was of help to me Kev. Thanks as well.


        ================================================================
        "A witty saying proves nothing."
        Voltaire (1694-1778)
        ================================================================
        It's a pretty day. I hope you enjoy it.

        Gösta

        JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
        LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

        Comment


        • #5
          Originally posted by Kev Peel View Post
          It's also probably best to use a console or msgbox to spit out debug info when you are testing. You'll find that placing "markers" around in the code will help to narrow down exactly where the GPF occurs.
          I've been using TRACE for just about all my debugging as of late. One of the best debugging features ever added to PB in my opinion. Message boxes have a tendency to really mess up code execution.

          James

          Comment


          • #6
            >the IsBadReadPtr/IsBadWritePtr

            That's a good tool, but be aware that it will not report *corruption* of memory you own.. it will only report attempts to access memory you don't own.
            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Originally posted by jcfuller View Post
              I've been using TRACE for just about all my debugging as of late. One of the best debugging features ever added to PB in my opinion.
              I agree, TRACE is great; just in a few cases I found preferable a messagebox, depending on what I was debugging.

              Originally posted by Michael Mattias View Post
              >the IsBadReadPtr/IsBadWritePtr

              That's a good tool, but be aware that it will not report *corruption* of memory you own.. it will only report attempts to access memory you don't own.
              Ah, thanks, good to know.

              Now I'm wondering, would accessing memory of another process necessarily cause an immediate GPF, or instead that might be a good system to ccorrupt memory in the good old way (that is, leading to a mess later) ?

              Comment


              • #8
                >would [attempting] accessing memory of another process necessarily cause an immediate GPF?

                Yes.

                (Assuming you are not using the ReadProcessMemory or WriteProcessMemory functions).

                One of the true beauties of win/32 vs win/16! One program can't accidentally bring down any other program.
                Michael Mattias
                Tal Systems Inc. (retired)
                Racine WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Overwriting global memory that you didn't allocate.... the memory directly after your allocated block could be in use by another allocation, so that memory is corrupted
                  A technical correction here..

                  You can't overwrite global memory you did not allocate. You get an immediate protection fault, not corruption. (Win/32). (or maybe now I should say Win/32+ ?)

                  Both STRING$ and GlobalAlloc allocate from the heap, which is about as close as any process can come to "global" memory.. but true "global memory" only exists in Win/32 when you create a system object (eg a memory mapped file) specifically for that purpose.

                  MCM
                  Michael Mattias
                  Tal Systems Inc. (retired)
                  Racine WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment

                  Working...
                  X