TEX7%ICNUCEVM.BITNET@MITVMA.MIT.EDU (Stefano Diomedi TECSIEL) (06/07/89)
I'm reporting a possible bug in gcc. GNU CC version: 1.35 Input File: ckudia.c in ckermit 4E(070) 29 Jan 88 After running 'gcc -E' you get: =============================================================================== # 1 "ckudia.c" char *dialv = "Dial Command, V2.0(009) 24 Jan 88"; # 1 "ckcdeb.h" typedef void SIGTYP; typedef unsigned char CHAR; typedef long LONG; # 116 "ckudia.c" # 1 "/usr/include/stdio.h" extern struct _iobuf { int _cnt; char *_ptr; char *_base; int _bufsiz; short _flag; char _file; } _iob[3]; extern struct _iobuf *fopen(), *fdopen(), *freopen(), *popen(), *tmpfile(); extern long ftell(); extern void rewind(), setbuf(), setbuffer(), setlinebuf(); extern char *fgets(), *gets(), *ctermid(), *cuserid(), *tempnam(), *tmpnam(); extern char *sprintf(); # 117 "ckudia.c" # 1 "/usr/include/ctype.h" extern unsigned short *_pctype; extern unsigned short _ctype__[]; # 118 "ckudia.c" # 1 "/usr/include/signal.h" struct sigvec { void (*sv_handler)(); int sv_mask; int sv_flags; }; struct sigaction { void (*sa_handler)(); int sa_mask; int sa_flags; }; struct sigstack { char *ss_sp; int ss_onstack; }; struct sigcontext { int sc_onstack; int sc_mask; int sc_sp; int sc_pc; int sc_ps; }; extern void (*signal())(); # 119 "ckudia.c" # 1 "ckcker.h" # 120 "ckudia.c" # 1 "ckucmd.h" struct keytab { char *kwd; int val; int flgs; }; # 121 "ckudia.c" # 1 "/usr/include/setjmp.h" typedef int jmp_buf[10]; extern int setjmp(); extern void longjmp(); # 124 "ckudia.c" extern int flow, local, mdmtyp, quiet, speed, parity, seslog; extern char ttname[], sesfil[]; struct mdminf { int dial_time; char *pause_chars; int pause_time; char *wake_str; int wake_rate; char *wake_prompt; char *dmode_str; char *dmode_prompt; char *dial_str; int dial_rate; }; static struct mdminf CERMETEK = { 20, "BbPpTt", 0, " XY\016R\r", 200, "", "", "", "\016D '%s'\r", 200 }; static struct mdminf DF03 = { 27, "=", 15, "\001\002", 0, "", "", "", "%s", 0 }; static struct mdminf DF100 = { 30, "=", 15, "\001", 0, "", "", "", "%s#", 0 }; static struct mdminf DF200 = { 30, "=W", 15, "\002", 0, "", "", "", "%s!", 0 }; static struct mdminf GDC = { 32, "%", 3, "\r\r", 500, "$", "D\r", ":", "T%s\r", 0 }; static struct mdminf HAYES = { 35, ",", 2, "AT\r", 0, "", "", "", "AT DP%s\r", 0 }; static struct mdminf PENRIL = { 50, "", 0, "\r\r", 300, ">", "k\r", ":", "%s\r", 0 }; static struct mdminf RACAL = { 35, "Kk", 5, "\005\r", 50, "*", "D\r", "?", "%s\r", 0 }; static struct mdminf UNKNOWN = { 30, "", 0, "", 0, "", "", "", "%s\r", 0 }; static struct mdminf USROBOT = { 30, ",", 2, "ATS2=01\r", 0, "OK\r", "", "", "ATTD%s\r", 0 }; static struct mdminf VENTEL = { 20, "%", 5, "\r\r\r", 300, "$", "", "", "<K%s\r>", 0 }; static struct mdminf CONCORD = { 35, ",", 2, "\r\r", 20, "CDS >", "", "", "<D M%s\r>", 0 }; static struct mdminf ATT7300 = { 30, "", 0, "", 0, "", "", "", "%s\r", 0 }; static struct mdminf *ptrtab[] = { &CERMETEK, &DF03, &DF100, &DF200, &GDC, &HAYES, &PENRIL, &RACAL, &UNKNOWN, &USROBOT, &VENTEL, &CONCORD, &ATT7300 }; struct keytab mdmtab[] = { "att7300", 13 , 0, "cermetek", 1, 0, "concord", 12, 0, "df03-ac", 2, 0, "df100-series", 3, 0, "df200-series", 4, 0, "direct", 0, 0, "gendatacomm", 5, 0, "hayes", 6, 0, "penril", 7, 0, "racalvadic", 8, 0, "unknown", 9, 0, "usrobotics-212a", 10, 0, "ventel", 11, 0 }; int nmdm = (sizeof(mdmtab) / sizeof(struct keytab)); static char *F_reason[5] = { "Unknown", "Timeout", "Interrupt", "Modem", "Initialize" }; static int tries = 0; static char lbuf[100]; static jmp_buf sjbuf; static SIGTYP (*savAlrm)(); static SIGTYP (*savInt)(); dialtime() { longjmp( sjbuf, 1 ); } dialint() { longjmp( sjbuf, 2 ); } static ttolSlow(s,millisec) char *s; int millisec; { for (; *s; s++) { ttoc(*s); msleep(millisec); } } static waitFor(s) char *s; { CHAR c; while ( c = *s++ ) while ( ( ttinc(0) & 0177 ) != c ) ; } static didWeGet(s,r) char *s, *r; { int lr = strlen(r); int i; for (i = strlen(s)-lr; i >= 0; i--) if ( s[i] == r[0] ) if ( !strncmp(s+i,r,lr) ) return( 1 ); return( 0 ); } static reset () { alarm(0); signal( 14 ,savAlrm); signal( 2 ,savInt); } ckdial(telnbr) char *telnbr; { char c; char *i, *j; int waitct, status; char errmsg[50], *erp; struct mdminf *pmdminf; int augmdmtyp; int mdmEcho = 0; int n, n1; char *pc; if (!mdmtyp) { printf("Sorry, you must 'set modem' first\n"); return(-2); } if (!local) { printf("Sorry, you must 'set line' first\n"); return(-2); } if (speed < 0) { printf("Sorry, you must 'set speed' first\n"); return(-2); } # 588 "ckudia.c" if (ttopen(ttname,&local,mdmtyp) < 0) { erp = errmsg; sprintf(erp,"Sorry, can't open %s",ttname); perror(errmsg); return(-2); } pmdminf = ptrtab[mdmtyp-1]; augmdmtyp = mdmtyp; waitct = 1*strlen(telnbr) ; waitct += pmdminf->dial_time; for (i=telnbr; *i; i++) for (j=pmdminf->pause_chars; *j; j++) if (*i == *j) { waitct += pmdminf->pause_time; break; } printf("Dialing thru %s, speed %d, number %s.\r\n",ttname,speed,telnbr); printf("The timeout for completing the call is %d seconds.\r\n",waitct); printf("Type the interrupt character to cancel the dialing.\r\n"); if ( tthang() < 0 ) { printf("Sorry, Can't hang up tty line\n"); return(-2); } if ( ttpkt(speed,4 ,parity) < 0 ) { printf("Sorry, Can't condition communication line\n"); return(-2); } if ( n = setjmp(sjbuf) ) { alarm ( 0 ); if ( n1 = setjmp(sjbuf) ) { printf ( "%s failure while handling failure.\r\n", F_reason[n1] ); } else { signal ( 14 , dialtime ); if ( signal ( 2 , ((void (*)())( 1)) ) != ((void (*)())( 1)) ) signal ( 2 , dialint ); alarm ( 5 ); ttclos (); } switch ( n ) { case 1 : { printf ( "No connection made within the allotted time.\r\n" ); break; } case 2 : { printf ( "Dialing interrupted.\r\n" ); break; } case 3 : { printf ( "Failed (\"" ); for ( pc=lbuf; *pc; pc++ ) if ( ((_pctype+1)[*pc]& (0020 |0001 |0002 |0004 |0200 )) ) (--((&_iob[1]))->_cnt>=0? ((int)(*((&_iob[1]))->_ptr++= (unsigned)(*pc))):_flsbuf((unsigned)(*pc),(&_iob[1]))); printf ( "\").\r\n" ); break; } case 4 : { printf ( "Cannot initialize modem.\r\n" ); break; } } reset (); return ( -2 ); } savAlrm = signal( 14 ,dialtime); if ( ( savInt = signal ( 2 , ((void (*)())( 1)) ) ) != ((void (*)())( 1)) ) signal ( 2 , dialint ); alarm(10); ttflui(); switch (augmdmtyp) { case 6: case ( 6 + ( 1<<8 ) ): while(tries++ < 4) { ttol( HAYES.wake_str, strlen(HAYES.wake_str) ); status = 0; while ( status <= 0 ) { switch (ttinc(0) & 0177) { case 'A': status = -3; break; case 'T': if (status == -3) { mdmEcho = 1; status = 0; break; } status = 2; break; case '\n': case '\r': status = 0; break; case '0': augmdmtyp = ( 6 + ( 1<<8 ) ); status = 1 ; break; case 'O': status = -2; break; case 'K': if (status == -2) { augmdmtyp = 6; status = 1 ; break; } default: status = 2; break; } } if (status == 1 ) break; if (status == 2) ttflui(); sleep(1); } if (status != 0) break; longjmp( sjbuf, 4 ); default: ttolSlow(pmdminf->wake_str, pmdminf->wake_rate); waitFor(pmdminf->wake_prompt); break; } alarm(0); msleep(500); alarm(10); ttolSlow(pmdminf->dmode_str, pmdminf->dial_rate); if (pmdminf->dmode_prompt) { waitFor(pmdminf->dmode_prompt); msleep(300); } alarm(0); alarm(waitct); ttflui(); sprintf(lbuf, pmdminf->dial_str, telnbr); ttolSlow(lbuf,pmdminf->dial_rate); if (augmdmtyp == 8) { sleep(3); ttflui(); ttoc('\r'); } status = 0; strcpy(lbuf,"No Connection"); while (status == 0) { switch (augmdmtyp) { default: for (n=0; n < 100; n++) { lbuf[n] = (ttinc(0) & 0177); if ( lbuf[n] == '\r' || lbuf[n] == '\n' ) break; } lbuf[n] = '\0'; if (n) { switch (augmdmtyp) { case 1: if (didWeGet(lbuf,"\016A")) { status = 1 ; ttolSlow("\016U 1\r",200); } break; case 3: case 4: if (didWeGet(lbuf,"Attached")) status = 1 ; if (didWeGet(lbuf,"Busy")) status = 2; if (didWeGet(lbuf,"Disconnected")) status = 2; if (didWeGet(lbuf,"Error")) status = 2; if (didWeGet(lbuf,"No answer")) status = 2; if (didWeGet(lbuf,"No dial tone")) status = 2; if (didWeGet(lbuf,"Speed:")) status = 2; break; case 5: if (didWeGet(lbuf,"ON LINE")) status = 1 ; if (didWeGet(lbuf,"NO CONNECT")) status = 2; break; case 6: case 10: if (didWeGet(lbuf,"CONNECT")) status = 1 ; if (didWeGet(lbuf,"NO CARRIER")) status = 2; break; case 7: if (didWeGet(lbuf,"OK")) status = 1 ; if (didWeGet(lbuf,"BUSY")) status = 2; if (didWeGet(lbuf,"NO RING")) status = 2; break; case 8: if (didWeGet(lbuf,"ON LINE")) status = 1 ; if (didWeGet(lbuf,"FAILED CALL")) status = 2; break; case 11: if (didWeGet(lbuf,"ONLINE!")) status = 1 ; if (didWeGet(lbuf,"BUSY")) status = 2; if (didWeGet(lbuf,"DEAD PHONE")) status = 2; break; case 12: if (didWeGet(lbuf,"INITIATING")) status = 1 ; if (didWeGet(lbuf,"BUSY")) status = 2; if (didWeGet(lbuf,"CALL FAILED")) status = 2; break; } } break; case 2: c = ttinc(0) & 0177; if ( c == 'A' ) status = 1 ; if ( c == 'B' ) status = 2; break; case ( 6 + ( 1<<8 ) ): c = ttinc(0) & 0177; if (mdmEcho) { mdmEcho = c!='\r'; break; } if (c == '1') status = 1 ; if (c == '3') status = 2; if (c == '5') status = 1 ; break; case 9: break; } } alarm(0); if ( status != 1 ) longjmp( sjbuf, 3 ); alarm(3); ttpkt(speed,5,parity); reset (); if ( ! quiet ) printf ( "Call completed.\07\r\n" ); return ( 0 ); } =============================================================================== Command: gcc -traditional -fwritable-strings -g -O -c ckudia.c Names of 'tm.h' and 'md' files: tm-vax.h and vax.md Machine type - Operating System name and version: DEC VAX 8200 Ultrix-32 V3.0 (Rev 64) Incorrect behaviour description: The optimizer produces the following assembly code for the 'setjmp' calls in the routine ckdial. C code: ... if ( n = setjmp(sjbuf) ) { alarm ( 0 ); if ( n1 = setjmp(sjbuf) ) { printf ( "%s failure while handling failure.\r\n", F_reason[n1] ); } else { signal ( 14 , dialtime ); Assembly code: L32: pushab _sjbuf movab _setjmp,r6 calls $1,(r6) movl r0,-92(fp) jeql L33 clrl -(sp) calls $1,_alarm pushab _sjbuf calls $1,(r6) movl r0,-96(fp) jeql L34 pushl _F_reason[r0] pushab LC107 calls $2,_printf jbr L35 L34: pushab _dialtime pushl $14 movab _signal,r6 calls $2,(r6) Sometimes I get an Illegal Instruction signal just in the second call to setjmp. It seems to me that the optimizer doesn't realize that register r6 can have a value different from _setjmp, if we have arrived here because of a longjmp call. I hope this can help you in finding the bug (!?). Regards Stefano Diomedi Tecsiel SpA Via S. Maria 19 56100 PISA Italy