www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/08/31/10:00:26

From: Michiel Uitdehaag <m DOT uitdehaag AT imn DOT nl>
Newsgroups: comp.os.msdos.djgpp
Subject: Re: keyword "new" causes SIGSEV
Date: Mon, 31 Aug 1998 15:32:57 +0200
Organization: World Online
Lines: 164
Message-ID: <35EAA608.D0F8C199@imn.nl>
References: <Pine DOT SUN DOT 3 DOT 91 DOT 980827140846 DOT 6326M-100000 AT is>
NNTP-Posting-Host: pc007.wkap.nl
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Hi,

I seem to be experiencing similar problems as the original poster and I'll
take the blame on my bad coding in advance :) At least, the edx register is
garbled when malloc crashes, so I obviously mess something up at some point.

First, the program output, including crash:
...
fragment = 12
now here in fragment2
Exiting due to signal SIGSEGV
Page fault at eip=0001ff5c, error=004
General Protection Fault at eip=0001ff5c
eax=00000004 ebx=00000000 ecx=fffffffc edx=20676e69 esi=00000003 edi=00000003
ebp=00085edc esp=00085ed4
program=C:\MYDOCU~1\MICHIEL\DJGPP\SOCKETS\HTTP\TEST.EXE

cs: sel=00a7  base=82d64000  limit=0009ffff
ds: sel=00af  base=82d64000  limit=0009ffff
es: sel=00af  base=82d64000  limit=0009ffff
fs: sel=0087  base=0000c320  limit=0000ffff
gs: sel=00bf  base=00000000  limit=ffffffff
ss: sel=00af  base=82d64000  limit=0009ffff

Call frame traceback EIPs:
  0x0001ff5c   _malloc+192
  0x0001bcf0   ___builtin_new+44, line 65535 of libgcc2.c
  0x0001c73f   ___builtin_vec_new+11, line 65535 of libgcc2.c
  0x00005511   _GetFragment__8URIClass+165, line 436 of uri.cpp
  0x00004905   _GetUri_8URIClass+293, line 52 of uri.cpp
  0x00002e5a   _SetURL_15HTTPSocketClassPc+138, line 169 of httpsocketc.cpp
  0x000042d2   _main+782, line 34 of test.cpp
  0x0001ea0e   ___crt1_startup+138

Eli Zaretskii already wrote (in response to this thread originating problem):

> The EDX register looks like text to me (0x20 is a blank, 0x07 is a ^G
> character), and _malloc+192 dereferences a pointer in EDX.

<snip>

I guess that 0x20 0x67 0x6e 0x69 is ascii (" gni"). Every crash, edx is
different though (just saw it being "t'no"). No part of my code inserts
anything like that (not even remotely, I swear).
Well, the GetFragment source:

char *URIClass::GetFragment()
{
/*  A fragment is:
 fragment       = *( uchar | reserved )
 MAY have one or more uchar, unreserved
 reserved       = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
 uchar          = unreserved | escape
 escape         = "%" HEX HEX
 unreserved     = ALPHA | DIGIT | safe | extra | national
 safe           = "$" | "-" | "_" | "."
 extra          = "!" | "*" | "'" | "(" | ")" | ","
 national       = <any OCTET excluding ALPHA, DIGIT,
                        reserved, extra, safe, and unsafe>

 Fragment is preceded by #
*/

// If no fragment, return NULL
 cout << "fragment = " << fragment << endl;
 char *frag;
 if(fragment==NULL) return NULL;
 int fraglen=strlen(fragment);
 if (fraglen==0) return NULL;
 cout << "now here in fragment" << fraglen << endl;

// line 436:
 frag=new char[fraglen+1];
 cout << "allocated memory" << endl;
// Unable to allocate memory
 if (frag==NULL) return frag;

/* A fragment is preceded by a # */
 cout << "going to copy" << endl;
 frag=strcpy(frag,fragment);
 cout << "returning fragment" << endl;
 return frag;
}

Eli Zaretskii also wrote:

> The problem is most probably not in the place it crashes, it happens
> before the crash.  Some code that is executed prior to that call to
> `malloc' overwrites a buffer allocated by another call to `malloc'.
> You need to find that place by tracing all allocations and how the
> buffers allocated are used.

I don't know if that applies to this routine. I declare a char * (frag) and
allocate memory to it using malloc(). I would assume that malloc does not
return a memory block that has not been freed yet. Before the malloc() / new
call, the pointer is not used

The function looks if the object currentlly has a 'fragment' string. If so, it
creates a new fragment memory block, copies the text into it and returns a
pointer to the allocated block. This block is subsequently used to read, copy
and be freed in the GetUri() function (only partially here):
char *URIClass::GetUri()
...
   if(HasFragment()) {
     cout << "getting fragment" << endl;
// line 52
     frag=GetFragment();
     fraglen=strlen(frag);
     fraglen=(fraglen==0)?0:fraglen+1;};
...
 if (fraglen>0) {
     uri=strcat(uri,"#");
     uri=strcat(uri,frag);};
 if (sm!=NULL) delete sm;
 if (uri1!=NULL) delete uri1;
 if (frag!=NULL) delete frag;
 return uri;
}

int HTTPSocketClass::SetURL(char *url)
{
 char *pt, *pt2, *pt3;
 Uri.SetUri(url);
 if(!Uri.HasScheme()) Uri.SetScheme("http:");
 cout << Uri.HasNetLoc();
 if (Uri.HasNetLoc()) {
// line 138
    pt=Uri.GetUri();
    cout << pt << endl;
    if (pt!=NULL) delete pt;};
...

and the relevant test call:
...
   delete pt;};
   cout << "now here" << endl;
   pt = new char[41];
//    pt=strcpy(pt,);
   cout << "setting URL" << endl;
// line 34
   http.SetURL("http://pc007.wkap.nl/index.html?hallo#12");
...

As can be seen from the program output, the fragment gets set correctly
(content = "12" and length is 2). I checked the allocation code for the object
variable "fragment" and it correctly 'newed' char[3]. Funny thing is,  the
whole program works fine 4 out of 5 times and crashes like this the 5th
(statistically, there's no predicting when it will crash).

If someone sees the blatantly obvious error right away, you're very free to
inform me ofcourse.

My second questions is: why would malloc() dereference a pointer that is not
supposed to point to anything? I mean, in:
        pointer = new char [12];
pointer gets assigned a value equal to the start of the 12 character block,
does it not? Who cares where 'pointer' pointed to before. That would be a
problem for 'delete pointer;'

Thanks for your time and trouble,

Michiel Uitdehaag
m DOT uitdehaag AT imn DOT nl

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019