Mail Archives: djgpp/1998/08/31/10:00:26
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 -