News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

A bug problem.

Started by minor28, April 20, 2012, 11:24:00 AM

Previous topic - Next topic

minor28

It is a windows project that deals with text. In a function I add one ascii character to a string. Doing so the app is unexpedtedly closed after a period of running. Without adding the character it is OK. I think it is because allocated memory is exceeded somewhere. Normally I find these errors with the debugger but not in this case. Debugging, the app is working OK. I cannot find the error.

The error must be caused by a combination of the original string and the fact that the string is expanded with one character. I have not been able find a string to reprocuce the error. How do I locate that special string.

All suggestions are welcome.

abnuque

Maybe in your declaration of .data you only have just enough string length such as:
.data
      str   db dup(10)
so when you add one more character it will exceed the length.
You got to show the code so that we can study its bug.

minor28

No, it is not that simple. You will not be helped to see the code. I would appreciate hints how to trace such errors.

jj2007

Quote from: minor28 on April 20, 2012, 11:44:32 AM
You will not be helped to see the code.

That attitude is not helpful.

HeapAlloc'ed memory is "tolerant", in the sense that you always get some bytes more than requested. Which is a recipe for bugs that are difficult to chase. Go and check if you requested enough memory for the strings you want to change.

minor28

Quote
That attitude is not helpful.

That is not my attitude in general and I am sorry if I expressed myself rude. That was not my intention. The code is written in more than 60 files and the section where the adding character is written cannot be of any help. The buffer for strings in question has enought space for one additional character.

I use HeapAlloc and I use HeapReAlloc.

jj2007

Ok, so you are up to some bug chasing...

hv MACRO arg
if 1 ; 0 to disactivate
  pushad
  xor esi, esi ; esi may point to some specific block, zero to validate entire heap
  invoke HeapValidate, rv(GetProcessHeap), 0, esi
  .if !eax
inkey "##### HV: &arg& ####", 13, 10
invoke ExitProcess, 0
  .endif
  popad
endif
ENDM


Usage:
   hv Loop in
   ... code ...
   hv Loop out
   ... code ...
   hv before ret
   ... code ...
   hv before call to my proc
   ... code ...

dedndave

Quote from: minor28 on April 20, 2012, 12:11:31 PM
The buffer for strings in question has enought space for one additional character.

maybe you are adding a character more than once

as Jochen mentioned, HeapAlloc generally allocates more than the requested amount
but - not always   :P
under the right conditions, it may allocate only what you ask for

on another note...
my experience has been that, if a program closes without an exception, it is usually caused by an imbalanced stack
so - you may be branching in some special case (or aggregate of special cases) to a point where the stack is not balanced

raymond

With the source code spread over some 60 different files, you may have a lot of fun finding the culprit. And I assume that one of those files contains the procedure to add characters to a string.

Have a very close look at that procedure, and the parameters it requires such as:
- counter for the number of characters to be appended
- source address of the character(s) to be appended
- address where the character(s) need to be appended
and the possibility of those parameters getting "contaminated".

Then look at all the files where that procedure is called and verify if some of the passed parameters could possibly have been "contaminated".

Also look at the procedures where you reallocate memory and how you modify the addresses for the new memory location(s) and where you store those modified addresses. Check that your other procedures calling for character insertion get the proper information for the source and destination addresses.

There may be a few hundred additional details to check but, without any code to look at, it would take several pages only to enumerate them.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

jj2007

Quote from: raymond on April 22, 2012, 03:17:48 AM
With the source code spread over some 60 different files, you may have a lot of fun finding the culprit.

Indeed. But it seems a widespread philosophy, especially among C programmers, that "modular is good". My medium sized sources (>500k) are single files, and that makes life a lot easier when chasing a bug. Oh well.

In case it isn't clear: The hv (heap verify) macro posted above is meant to be inserted before and after calls to subroutines, e.g.
start:
  hv before start
  call main
  hv after start

main proc

  ...
  hv before sub1
  call sub1
  hv after sub1

sub1 proc
  ...
  hv before subX
  call subX
  hv after subX

Somewhere it will crash. Look at the crash point, go a level deeper with the hv macro, e.g. before and after loops, and eventually Sherlock Holmes will succeed in finding the culprit. If the culprit is heap corruption, that is. If not, let hv print a single character and see where it stops printing, e.g.
AAAABBBBCCBBCCBBCCBBA <bang, now go back and try to find out where it stops.

Of course, Olly does a good job, too, but it's not always the best option.

dedndave

i have said it before....
placing a temporary Beep at specific locations can be a powerful tool   :P
if you want to know if something is happening more than once - it will tell you
if you want to know if one thing happens before another - use different tones
make them short bursts - like 30 or 40 ms
and - it is easy to code - lol

        .if uMsg==WM_GETMINMAXINFO
            invoke  Beep,700,40
        .elseif uMsg==WM_SIZE
            invoke  Beep,300,40


of course, it sucks if you are using vista
but that was true, anyways

raymond

Such a beep inserted whenever you reallocate memory would at least let you know if the program crashes before, or only after, you reallocate memory. It could reduce considerably your search space.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

minor28

I have gone through each memory block and I've used both beep and messagebox. I could not find anything wrong in handling the memory.

It took quite a long time but when I did the review I did some changes in the codes dealing with the strings and suddenly it worked. I cannot reproduce the bug so I don't know what was wrong. I don't think it was an unbalanced stack problem. Probably a memory problem anyway. Perhaps I was careless with a trailing zero somewhere.

Thank you for your help

evlncrn8

dit causes an exception presumably....
so setup ollydbg as jit, run program, wait for crash, look at stack dump for nearest function.. correspond this with the map / pdb of the compiled exe, should get you quite close

dedndave

well - if you can't reproduce it, it will be hard to fix it

i have come across similar situations in electronic ciruitry
you have to find a way to force it to happen before you can fix it

jj2007

Quote from: dedndave on April 24, 2012, 11:19:13 AM
well - if you can't reproduce it, it will be hard to fix it

Apparently, the bug has been "unconsciously fixed" - Murphy's Law says it will resurface when you really don't need it :green