X-Authentication-Warning: delorie.com: mail set sender to djgpp-bounces using -f X-Received: by 10.224.174.145 with SMTP id t17mr7618577qaz.4.1371460683820; Mon, 17 Jun 2013 02:18:03 -0700 (PDT) X-Received: by 10.50.36.41 with SMTP id n9mr394152igj.11.1371460683780; Mon, 17 Jun 2013 02:18:03 -0700 (PDT) Newsgroups: comp.os.msdos.djgpp Date: Mon, 17 Jun 2013 02:18:03 -0700 (PDT) Complaints-To: groups-abuse AT google DOT com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=71.222.72.40; posting-account=jrLHRgkAAABPV01ZW_RN_U6Tm5UnYNUx NNTP-Posting-Host: 71.222.72.40 User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <36e857f0-9899-496b-9fc6-32251e109888@googlegroups.com> Subject: General Protection Fault error is intermittent From: "K.J.Williams" Injection-Date: Mon, 17 Jun 2013 09:18:03 +0000 Content-Type: text/plain; charset=ISO-8859-1 Bytes: 11134 Lines: 377 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by delorie.com id r5H9U1ue017760 Reply-To: djgpp AT delorie DOT com Hi, I have a problem with why a General Protection Fault message is not displayed all the time, for a function called string_parser in two different programs. The function called string_parser uses a string.h function called strtok(). I am trying to implement it to work right, and I know that I am not doing it correctly. But the question is why in a smaller program it compiles fine and doesn't exhibit the General Protection Fault message vs. when I implement it in a larger program it does ? heres my source code : /* program name: parstext.c author: K.J.Williams Purpose: This is a sample of how string_parser, which uses strtok() is used parse commands in the larger program that I am developing called ( by acronym ) WATT. */ #include #include // original design setting: #define PARSE_SIZE_LIMIT 81 //function prototypes: short int string_parser(char *, char *, char, short int);//TEXT_PARSER short int kfgets(char *);//KFGETS short int ynreturn(void);//yes/no option short int return_key(void);//waits for user to press ENTER int main (void) { //declare char arrays and initialize garbage with '\0' char target[PARSE_SIZE_LIMIT];//user input char worda[PARSE_SIZE_LIMIT]; worda[0] = '\0';//command statement char uword[PARSE_SIZE_LIMIT]; uword[0] = '\0';//argument part //temporary variables short int counta,countb,x,y,z; char d;//for first character of a string //message printf("Compilation Date : %s @ %s PST (24hr format)\n",__DATE__,__TIME__); printf("WATT: single text line string parsing tester\n"); printf("Enter AT Command (ATcmd) statment(s) in the syntax format of\n"); printf("[#(ATcmd): arg1 arg2 ... argN ] or [#(ATcmd): ] - for no args, and etc.\n"); //prompt user do { //initialize (or reset) these variables z = 1; target[0] = '\0'; //prompt user printf("\n>"); kfgets(target);//use my fgets function d = target[0]; if(d != '#') { return 0; }// if the first character != '#' then exit... if( (string_parser(target,worda,'#',-2)) == -1) { printf("text line uses incorrect syntax with adjacent \'#\' characters\n"); return 0; } //otherwise begin parsing.... counta = string_parser(target,worda,'#',-1);//count tokens & do nothing string_parser(target,worda,'#',0); printf("[%s]\n..has %d part(s) counted by \'#\'\n\n",worda,counta); //parsing each statement and argument by '#', then ' '. do { for(x = 1;x <= z;x++) { string_parser(target,worda,'#',x); } printf("part#%d : %s\n",x-1,worda);//-1 for x counter offset countb = string_parser(worda,uword,' ',-1); string_parser(worda,uword,' ',0); printf("[%s]\n..has %d sub-part(s) counted by \' \'\n",uword,countb); //if countb == 0 - then do nothing if(countb == 1) { string_parser(worda,uword,' ',1); printf("...sub-part#1 : %s\n",uword); } if(countb > 1) { for(y = 1;y <= countb;y++) { string_parser(worda,uword,' ',y); printf("...sub-part#%d : %s\n",y,uword); } } //pause if(z < counta); { return_key(); } z++; //end of do..while loop }while(z <= counta); printf("\ntest again (y/n)?"); //outer do...while loop } while((ynreturn()) == 1); return 0; } //parses c strings by using single character tokens with strtok(); short int string_parser(char *userstring, char *target, char magic, short int word) { char subject[PARSE_SIZE_LIMIT]; subject[0] = '\0'; //initialize subject //w1 = token with null character ; w2 = token without null character char w1[2]; w1[0] = magic; w1[1] = '\0'; char w2[1]; w2[0] = magic; //temp variables: char a = 0;//copies x before the if evaluation of x - see below char b = 0;//copies b after the if evaluation of x - see below char c = 0;//the difference between a & b - see below char d = 0;//d = subject[x]; - see below char x = 0;//for loop counter char y = 0;//counts the number of times a magic is in userstring (subject) //only if (c > 1) char z = 0;//same use as y, but with out the condition of if (c > 1) //for use only when word = -2 short int length;//get the length of the string subject char *p;//used for assigning pointer address returned by strtok() strcpy(subject,userstring);//copy userstring to subject length = strlen(subject);//get length of subject //printf("\n");//temp //printf("subject = %s\n",subject);//temp //printf("word = %d\n",word);//temp //printf("length = %d\n\n",length);//temp //return the number parts in the string if(word == -1 || word == -2) { //count where all the "magic" characters are for(x = 0;x < length;x++) { d = subject[x];//copy the character value to d //printf("%c : %c =",d,magic);//temp //if the subject character = "magic" character then count it if(d == magic) { if(word == -2) { z++; } //increment z regardless of where magic is found for word -2 a = x;//set a to x , to match where x is currently at. if(x == 0) { y++; } if(x > 0) { c = a - b;// c = the new count (of x) - the old count (of x) //a magic character must have a difference between it's last //position (if there is one) and its new position ( which is greater //than 1 ) to be counted as magic character. Therefore, if "#" is a //magic character and a string is, "##magic:" it would be discounted. //However, a string such as,"# #magic:" would be counted as two //magic characters. //When word == -2 an additional check that the same number of //magic characters found anywhere in subject are the same number //of magic characters that are at least spaced apart by at least 2 //characters. if(c > 1) { y++; } // if c > 1 then increment y } b = a;//set b to a , to save the previous count (of x) //printf(" true : y = %d\n",y);//temp } else { //printf("false\n");//temp - do nothing } //end of for loop } if (word == -2) { if(z != y) { return -1; } } return y; } // just copy the string - a do nothing feature if(word == 0) { strcpy(target,subject); return 0; } //** this is where strtok() is used ** /* note: strtok expects the token to be a cstring without a null character on the first use, and a token to be a cstring *with* a null character every use after the first. */ //copy the first word in the string (must be done to find the next words) if(word == 1) { p = strtok(subject,w2); strcpy(target,p); } //copy the next word sequencially in the string as word increments by 1 if(word > 1) { p = strtok(NULL,w1); strcpy(target,p); } return 0; } //generic prompt and get text from user short int kfgets(char *target) { short int a;//temp. variables char line[PARSE_SIZE_LIMIT]; line[0] = '\0'; //temp string storage //programmer must provide a prompt for whatever information wanted //from the user fgets(line ,PARSE_SIZE_LIMIT, stdin); a = strlen(line); line[a-1] = '\0';//get rid of the newline character added by fgets strcpy(target,line);//copy line to the target array return 0; } //a simple (yes/no) branch short int ynreturn(void) { short int result = 0; char x[3]; while (fgets(x,3,stdin) != NULL && x[1] != '\n'); switch(x[0]) { case('Y'): case('y'): { result = 1; break; } case('N'): case('n'): { result = 0; break; } //for garbage default: { result = 0; break; } } return result; } //a ANSI C equivalent of " Press any key to continue " short int return_key(void) { char x[2]; printf("\n Press Enter...\r"); while (fgets(x,2,stdin) != NULL && x[0] != '\n'); return 0; } (end of code) Now, as previously stated, the program compiles fine ( I am using DJGPP for Windows 95 in MS-DOS ) and runs without a complaint. But when I implement it in my bigger program, called WATT... I get : Exiting due to signal SIGSEGV General Protection Fault at eip=000093a3 eax=49420001 ebx=0001b500 ecx=00000000 edx=00000006 esi=0001b5b4 edi=0009d5c4 ebp=0009d508 esp=0009d4a0 program=C:\DJGPP\PROGRAMS\WATT.EXE cs: sel=0187 base=8395b000 limit=000bffff ds: sel=018f base=8395b000 limit=000bffff es: sel=018f base=8395b000 limit=000bffff fs: sel=0167 base=000113b0 limit=0000ffff gs: sel=019f base=00000000 limit=0010ffff ss: sel=018f base=8395b000 limit=000bffff App stack: [0009d7f0..0001d7f0] Exceptn stack: [0001d74c..0001b80c] Call frame traceback EIPs: 0x000093a3 0x000065c5 0x00005d0e 0x0000bd68 (end of message) As you can see, from parstext.c strtok() is returning a NULL pointer which is not being checked for in either program. So I am trying to figure out why the parstext.c program is not triggering this General Protection Fault message? Thanks. KJW