Solved

BC++ 4.5 stackoverflow

Posted on 1997-11-27
7
336 Views
Last Modified: 2012-06-22
I have a big C++ program. When compiling it via DOS:
BCC test.c -mm -N      (check stack, medium memory model)
Compiling goes OK (no warnings), when executing I get the msg: Stackoverlow! Changing memory model does not solve it.
When compiling under Solaris (CC), it runs fine (on a sun).
How can I check if it is a pointer problem and how can I solve it?
0
Comment
Question by:polleke
  • 4
  • 3
7 Comments
 
LVL 1

Accepted Solution

by:
TheMadManiac earned 200 total points
ID: 1174261
hi polleke,

the problem with dos is: you have limited memory
so when you have a little struct like this:

struct foo
   {
   char data[32000];
   };

and a function like this:

void function()
   {
   struct foo my_foo[2];  // this will eat up 64000 bytes of stack !!
   
   /*usually some code here...*/
   }

this will now take up 64000 bytes of stack, which is usually to much.

there are a few ways to deal with this.

 1: make the stack bigger
   #include <dos.h>
   extern unsigned _stklen=50000U;  // creates a stack of 50000 bytes.
   (this is limited to 64K in realmode !!, which is a real pain in the arse if you are using recursive functions)

 2: don't use data on the stack too much, but allocate it dynamically

   void function()
     {
     struct foo *my_foo;

     my_foo=new foo;

     /* again some code */
     }

  3: be evil and make large data-variables global
     ( i wouldn't do this if i were you... )

    struct foo my_foo;
    void function()
      {
      /* use my_foo as usuall*/
      }

with borland C++ 3.1 the stack was defined as 4KB, which is usually not enough. I suppose in BC4.5 it would be a little bigger, but not much.

this stack problem is not only with bc4.5, but with ALL dos programs

hope this helps,

 TheMadManiac/Florizzzzz
0
 

Author Comment

by:polleke
ID: 1174262
Florizzz,

My C sourcefile is approx 256kB long. On my SUN station it
compiles and runs OK when using CC. On my PC it gives
pointererrors and stackoverflow.
I am using BC++ 4.5 with standard settings (no makefile).
When I remove a few printf-lines, it compiles and runs OK.
When I exclude the code with /* ... */, it compiles OK,
but gives a stackoverflow or pointererror (garbled output).
Compiling using huge model does not matter. When checking
the stacksize (-N) option, it does not give a warning.

I tried the solution you mentioned in option 1 (the easiest one):
#include <dos.h>
extern unsigned _stklen=50000U;
But now I get abnormal program termination (when executing. Compiling goes OK)

Hints??????

Grtx Polleke
0
 
LVL 1

Expert Comment

by:TheMadManiac
ID: 1174263
Polleke,

the only thing i can think of is that some memory-allocation doesn't succeed. (remember, normal DOS programs do not use memory above 640kb. To use the memory above 1mb you either have to use protected mode, EMS, XMS or some dpmi manager)

On a SUN with solaris memory isn't really a big problem, and allocations usually (if not always) succeed.

When you allocate some memory with malloc/calloc/etc functions,
it returns NULL when the allocation does not succeed. My guess is this happenes somewhere and you don't check for it.

If you have 256kb of code, it might be hard to find where it goes wrong. You could override the normal malloc with a define like this:

#define malloc Malloc

and then create a function called Malloc which call's malloc, and checks if the returned pointer is NULL, and if so, write's a debug-line to the standard error device (or file or whatever) and/or terminate the program

so, you could get something like:

void *Malloc(size_t size)
  {
  void *foo=malloc(size);
  if (foo==NULL)
    {
    printf("allocation failed");
    exit(-1);
    }
  return foo;
  }

this makes it easy to find memory-alocation failures, and if everything works ok, you can remove the define and the normal malloc will be called again. Thus no modification to existing code is needed.

since it's a little uncertain to me if it is a c or c++ source (since you mentioned both) i'll also tell you how to check for memory-allocation failures using 'new' in bc4.5 and up

if a 'new' allocation failes, a xerror is thrown, which you should then catch:

#include <except.h>

void function()
  {
  char *foo;

  try {
      foo=new char[640000L]; // note, this WILL fail
      /*
      now do some operation on foo, or not.
      */
      }
  catch(xalloc){ //this block is only entered when the new fails!
    printf("allocation error.. bye\n");
    exit(-1);
    }

 // after this point, foo is allocated and can be used


I hope this might help you solve your problem,

 TheMadManiac/Florizzzz
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

Author Comment

by:polleke
ID: 1174264
Florizzz,

I use just plain-C, but the CC++ compiler in old C-mode (default). I tried the option you mentioned, but I did not get an allocation error. When I played around with the _stklen, I found out that _stklen=5500U gives Stackoverflow and _stklen=5800 gives abnormal program termination.

Other hints?

Polleke
0
 
LVL 1

Expert Comment

by:TheMadManiac
ID: 1174265
sorry for the delay,

borland assumes DS == SS in medium model, thus limiting data & stack to 64k. If this is not enough, try the -mm! compiler option. With this, stack & data segment are different.
(don't think this will help, but you never know)

i can't tell you what causes the overflow other than the stack being to small), but i can explain the abnornal termination i think.

stackchecking is only done in your code, not in the library's that come with the compiler. So, if you call a function that uses a little stack of it's own (most of them do) and the stack is about to overflow, this is not checked, and it's overflown withouth the stack-ckecking mechanism knowing it. This can cause the data segment to get corrupted (medium model SS == DS) which in turn can cause an abnormal program termination.

In other words, 5800 stack doesn't seem to be enough

Other than that, i haven't got a clue. It is always difficult to track down the problem with this kind of stuff.

greets,
  The Mad Maniac/Florizzzzz
0
 

Author Comment

by:polleke
ID: 1174266
Florizz,

When compiling with "bcc -mm!", I got a lot if "Suspicious pointer conversion in function ..."-warning messages. The following functions came up quite a few times.
I wrote it in very clean C since other people are also involved (so no short if-then-else-notations or too-encrypted-recursive-functions). I can not find any suspicious pointer conversions in the functions beneath.
Can you?

Regards Polleke


/* remove all spaces from a line */
char *shrink(char *s)
{
    char temp[N_LINE];
    char *t=s;         /* s = begin address of forwarded string */
    int loop=0;

    while (*t)
        if (isspace(*t))
            t++;
        else
        {   temp[loop++]=*t;
            t++;
        }
    temp[loop]='\0';
    strcpy(s, temp);
    return s;
}



/* look for a character in a string and return location */
int findchar(char *s, char c)
{
    int loop=0;

    while (*(s+loop)!='\0' && *(s+loop)!=c)
        loop++;
    if (*(s+loop)==c)
        return loop;
    else
        return(-1);
}



/* convert hex-char to an integer */
int hex2int(char c)
{
    int n;

    if (c>='A' && c<='F') n=c-55; else n=c-48;
    if (n<0) n=0;
    return n;
}


0
 
LVL 1

Expert Comment

by:TheMadManiac
ID: 1174267
polleke,

when using medium memory-model, default for code-pointers are far, and for data-pointers near. (notice that near = 16 bits)

thus, a 'char *foo;' will create a pointer which only contains the offset from DS (or SS, in case of stack)
a 'char far *foo;' will create a segment:offset pointer.

needless to say, when DS != SS, it doesn't know the segment and voila, suspicous pointer conversion.

you could use char far pointers, or just use the large memory model, where all pointers are default far.

btw, for findchar you could use strchr, which does almost the same. it's in string.h

TMM/florizzzz
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now