From: Michiel Uitdehaag 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: NNTP-Posting-Host: pc007.wkap.nl Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk 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. 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 = 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