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