[Hamlib-developer] Hamlib Segfault (rig with rig_set_trn along with dummy)
Library to control radio transceivers and receivers
Brought to you by:
n0nb
|
From: Chuck H. <n2...@am...> - 2002-09-28 10:17:15
|
Here is my entry for the Segfault-award :)
If you:
Open one rig (I happen to use an Icom).
call rig_set_trn to enable notifications from the rig if you turn the kno=
b.
Open dummy as a second rig.
Try to do anything with the first rig.
It will segfault in search_rig_and_decode when attempting to check to see=
if
there is any input on the fd associated with dummy. Because dummy doesn'=
t have
a fd when it tries to call FD_SET with a fd of -1.
There's even a note at the top of search_rig_and_decode saying it assumes=
the
fd is valid (>=3D0).
I'd submit a patch, but I wasn't sure how you wanted to fix it:
1. Dummy for now could be a special case that doesn't have a fd.
(May blow up later when they start putting network interfaces on rigs)
2. Check for fd =3D=3D -1
3. Do you want to check for input if rig_set_trn is not set for that rig?
4. Something else?
Attached are:
1. The bit of code that has the bug
2. A run of my test program.
3. The source to my test program.
PS No, I didn't go out trying to find this. :)=20
I figured I'd add transmitter support to my satellite doppler program.=
=20
However, I didn't have a handy computer controllable radio. So I fig=
ured
I'd use my Icom R7000 as a receiver and dummy as the transmitter for
testing.)
-----------------------------------------------------------------------
The portion of the code that it segfaults in (from src/event.c):
/*
* This is used by sa_sigio, the SIGIO handler
* to find out which rig generated this event,
* and decode/process it.
*
* assumes rig!=3DNULL, rig->state.rigport.fd>=3D0
*/
static int search_rig_and_decode(RIG *rig, rig_ptr_t data)
{
fd_set rfds;
struct timeval tv;
int retval;
#if 0&&defined(HAVE_SIGINFO_T)
siginfo_t *si =3D (siginfo_t*)data;
if (rig->state.rigport.fd !=3D si->si_fd)
return -1;
#else
FD_ZERO(&rfds);
FD_SET(rig->state.rigport.fd, &rfds);
----------------
It segfaults on the FD_SET because fd =3D -1.
-------------------------------------------------------------------------=
--
A run of my test program:
[kmh@wanderer2 test.mult]$ gdb ./test_mult=20
GNU gdb Red Hat Linux (5.1.90CVS-5)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you =
are
welcome to change it and/or distribute copies of it under certain conditi=
ons.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for detail=
s.
This GDB was configured as "i386-redhat-linux"...
(gdb) run
Starting program: /export/wanderer2/kmh/track/test.mult/test_mult=20
At the beginning
rig:rig_init called=20
rig: loading backend icom
icom: _init called
rig_register (309)
rig_register (310)
rig_register (311)
rig_register (313)
rig_register (319)
rig_register (330)
rig_register (326)
rig_register (327)
rig_register (347)
rig_register (334)
rig_register (344)
rig_register (335)
rig_register (340)
rig_register (342)
rig_register (304)
rig_register (307)
rig_register (300)
rig_register (352)
rig_register (353)
rig_register (351)
rig:rig_open called=20
rig1 (icom) =3D 0x804a3b8
rig:rig_init called=20
rig: loading backend dummy
dummy: _init called
rig_register (1)
dummy_init called
rig:rig_open called=20
dummy_open called
dummy_get_vfo called: VFOA
rig2 (dummy) =3D 0x804b9d8
Everything opened
TX 6 bytes
0000 fe fe 08 e0 03 fd ......
sa_sigioaction: activity detected
Program received signal SIGSEGV, Segmentation fault.
0x4001eda4 in search_rig_and_decode (rig=3D0x804b9d8, data=3D0xbffff4d0)
at event.c:138
138 FD_SET(rig->state.rigport.fd, &rfds);
(gdb) print rig->state.rigport.fd
$1 =3D -1
(gdb) bt =20
#0 0x4001eda4 in search_rig_and_decode (rig=3D0x804b9d8, data=3D0xbffff4=
d0)
at event.c:138
#1 0x40017d85 in foreach_opened_rig (cfunc=3D0x4001ed60 <search_rig_and_=
decode>,=20
data=3D0xbffff4d0) at rig.c:180
#2 0x4001ee74 in sa_sigioaction (signum=3D29, si=3D0xbffff4d0, data=3D0x=
bffff550)
at event.c:180
#3 <signal handler called>
#4 0x401102de in select () from /lib/libc.so.6
#5 0x400293dc in __DTOR_END__ () from /opt/hamlib/lib/libhamlib-1.1.4-cv=
s.so.0
#6 0x4018b1f6 in read_icom_frame (p=3D0x804a3bc, rxbuffer=3D0xbffff9b0
"\017\n\004")
at frame.c:236
#7 0x4018b0a2 in icom_transaction (rig=3D0x804a3b8, cmd=3D3, subcmd=3D-1=
,=20
payload=3D0x0, payload_len=3D0,=20
data=3D0xbffffa20 " \002\003@ \223\002 L\001@ ,\001 =B9\004\b $\001=
@
&\001@\024", data_len=3D0xbffffa1c) at frame.c:132
#8 0x40188524 in icom_get_freq (rig=3D0x804a3b8, vfo=3D0, freq=3D0xbffff=
ab8)
at icom.c:376
#9 0x400187cb in rig_get_freq (rig=3D0x804a3b8, vfo=3D0, freq=3D0xbffffa=
b8)
at rig.c:705
#10 0x0804897b in main () at test_mult.c:98
#11 0x400510c4 in __libc_start_main () from /lib/libc.so.6
(gdb)
----------------------------------------------------------------------
A little test program I wrote to demonstrate the problem:
You will have to modify the first open_rig call in main for your radio.
#include "hamlib/rig.h"
#define ICOM_SET_TRN_NEEDED
#define OPEN_RIG2
int process_freq_event(RIG *xrig, vfo_t xvfo, freq_t xfreq,rig_ptr_t xpda=
ta)
{
int slot;
char message_buf[1024];
struct radio_connection_struct *pradio_connection;
printf("Rig %p changed freq to %lli Hz\n",xrig,xfreq);
}
RIG *open_rig(int xkey,int rig_type,char *prig_pathname,char *pserial_spe=
ed)
{
RIG *prig;
int x;
prig =3D rig_init(rig_type);
if(!prig)
{
printf("Problems with init_rig\n");
return(0);
}
if(prig_pathname)
{
x =3D rig_set_conf(prig,rig_token_lookup(prig,
"rig_pathname"),prig_pathname);
if(x !=3D RIG_OK)
{
printf("Problem rig_set_conf setting rig_pathname to
'%s'\n",prig_pathname);
return(0);
}
}
if(pserial_speed)
{
x =3D rig_set_conf(prig,rig_token_lookup(prig,
"serial_speed"),pserial_speed);
=20
if(x !=3D RIG_OK)
{
printf("Problem %d with rig_set_conf setting serial_speed to
'%s'\n",x,pserial_speed);
return(0);
}
}
=20
x =3D rig_open(prig);
if(x !=3D RIG_OK)
{
printf("Problem %d with rig_open\n",x);
return(0);
}
=20
return(prig);
}
main()
{
RIG *prig1;
RIG *prig2;
freq_t freq_hz;
int x;
printf("At the beginning\n");
rig_set_debug(RIG_DEBUG_TRACE);
/* Set appropriately for your rig: */
/* prig1 =3D open_rig(0,340,"/dev/ttySp4","9600"); */
prig1 =3D open_rig(0,340,0,"9600");
printf("rig1 (icom) =3D %p\n",prig1);
#ifdef ICOM_SET_TRN_NEEDED
rig_set_freq_callback(prig1, process_freq_event, 0);
=20
x =3D rig_set_trn(prig1, RIG_TRN_RIG);
=20
if (x !=3D RIG_OK ) {
printf("WARNING: rig_set_trn (rig1): Error =3D %s \n", rigerror(x));
} =20
#endif
#ifdef OPEN_RIG2
prig2 =3D open_rig(0,1,0,0);
printf("rig2 (dummy) =3D %p\n",prig2);
#endif
printf("Everything opened\n");
x =3D rig_get_freq(prig1,RIG_VFO_CURR,&freq_hz);
=20
if(x !=3D RIG_OK)
{
printf("problems with rig_get_freq\n");
printf("x =3D %d\n",x);
printf("rigerror =3D '%s'\n",rigerror(x));
return;
} =20
printf("\nfreq =3D %ld\n",freq_hz);
printf("At the end\n");
}
|