Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtkrcv 3.4.3 b26 Segmentation fault #272

Open
zuliani71 opened this issue Feb 1, 2017 · 17 comments
Open

rtkrcv 3.4.3 b26 Segmentation fault #272

zuliani71 opened this issue Feb 1, 2017 · 17 comments

Comments

@zuliani71
Copy link

Dear all
i'm trying rtkrcv both on my mac and on my linux machine. I've compiled and installed the source code without errors but when I run the command:
rtkrcv -s -p 2950 -o myconf.conf
I get: Segmentation fault

I've tried the same myconf.conf file with a previous 3.4.3 b16 release and it works.
Can you help me?

@cstrobel-iis
Copy link

This error was added with version 2.4.3 b24, if you run rtkrcv with option "-s". If you start the rtk server manually, it works.

@sezeryalcin
Copy link

I confirm this issue. Manual starting works. Automatic start causes SEGFAULT.

@sezeryalcin
Copy link

This is ARM Debian 8 (raspian jessie)

@tizianoC
Copy link

Hallo,

Me too had the same problem working with the version of rtklib 2.4.3 b26 on a raspberry. The option -s in this version gives rise to a segmentation fault (on the contrary, this option for rtklib 2.4.2 worked fine...).

Any hint how to fix it?

Thank you

@zuliani71
Copy link
Author

zuliani71 commented Apr 26, 2017 via email

@sezeryalcin
Copy link

Going back to prior version is a temp fix. Looks like b24 changes broke it.

@sezeryalcin
Copy link

Any ETA for fix?

@sezeryalcin
Copy link

sezeryalcin commented Jul 17, 2017

I checked and saw some poorly implemented and threading causing this issue. Here is a quick+dirty but working fix if you want to use autostart:

You should add lines with + and recompile rtkrcv.
You SHOULD NOT use -s option at start. -s option is executing these obsolete lines and causing segfault:
/* start rtk server */
if (start) {
startsvr(NULL);

When you do this patch, RTKRCV will ALWAYS AUTOSTART. I think this is the right way anyways, Again, don't use -s option.

So HERE IS THE FIX: In rtkrcv.c ONLY:

*** 1283,1292 ****
--- 1283,1294 ----
          "navidata","stream","error","option","set","load","save","log","help",
          "?","exit","shutdown",""
      };
      con_t *con=(con_t *)arg;
      int i,j,narg;
+     static int autostart = 1;
      char buff[MAXCMD],*args[MAXARG],*p;
      
      trace(3,"console_thread:\n");
      
      vt_printf(con->vt,"\n%s** %s ver.%s %s console (h:help) **%s\n",ESC_BOLD,
***************
*** 1300,1309 ****
--- 1302,1318 ----
      while (con->state) {
          
          /* output prompt */
          if (!vt_puts(con->vt,CMDPROMPT)) break;
  
+         if (autostart)
+         {
+            autostart = 0;
+            cmd_start(args, narg, con->vt);
+         }
+ 
          /* input command */
          if (!vt_gets(con->vt,buff,sizeof(buff))) break;
          
          if (buff[0]=='!') { /* shell escape */
              cmd_exec(buff+1,con->vt);

@sezeryalcin
Copy link

Just tested my patch and it works. You should not use -s. It will just auto start the server without it. Using -s causes it to segfault.

@kme-it
Copy link

kme-it commented Jan 23, 2020

Sry to warm up an old issue even though it's not solved yet.

I ran into the same issue, but the "patch" from @sezeryalcin didn't work for me, as that one requires a login into the rtkrcv app, or into one of the virtual terminals via telnet or something like that. My usecase requires a standalone start.

So I don't have a real fix, but I went a little bit deeper into the code and the problem is essentially that the app can't print its messages somewhere as there is neither a virtual terminal or a real one. So under the assumption that the app is started headless and no one connects via telnet, there is no use in printing the messages at that point.
I know one might not get messages or something which one should probably read, but starting a application headless would mean one is pretty sure everything is covered anyhow.
My fix actually automatically overwrites old output/log files, so be sure you want that.

Fixing it the right way would need a more thorough rewrite of that part of the message handling process.

--- app/rtkrcv/rtkrcv.c   2019-08-19 11:04:50.000000000 +0200
+++ app/rtkrcv/rtkrcv.c   2020-01-22 16:34:41.958287971 +0100
@@ -420,8 +420,12 @@ static int startsvr(vt_t *vt)
         else cmds_periodic[i]=s2[i];
     }
     /* confirm overwrite */
-    for (i=3;i<8;i++) {
-        if (strtype[i]==STR_FILE&&!confwrite(vt,strpath[i])) return 0;
+    if(vt != NULL)
+    {
+        for (i = 3; i < 8; i++)
+        {
+            if (strtype[i] == STR_FILE && !confwrite(vt, strpath[i])) return 0;
+        }
     }
     if (prcopt.refpos==4) { /* rtcm */

--- app/rtkrcv/vt.c	2019-08-19 11:04:50.000000000 +0200
+++ app/rtkrcv/vt.c	2020-01-22 15:46:24.239567477 +0100
@@ -106,7 +106,8 @@ extern void vt_close(vt_t *vt)
     int i;
     
     trace(3,"vt_close:\n");
-    
+    if(vt == NULL)
+        return;
     /* restore terminal mode */
     if (!vt->type) {
         tcsetattr(vt->in,TCSANOW,&vt->tio);
@@ -121,6 +122,8 @@ extern void vt_close(vt_t *vt)
 /* clear line buffer ---------------------------------------------------------*/
 static int clear_buff(vt_t *vt)
 {
+    if(vt == NULL)
+        return 0;
     char buff[MAXBUFF*3],*p=buff;
     int i,len=strlen(vt->buff);
     for (i=0;i<vt->cur;i++) *p++='\b';
@@ -132,6 +135,8 @@ static int clear_buff(vt_t *vt)
 /* refresh line buffer -------------------------------------------------------*/
 static int ref_buff(vt_t *vt)
 {
+    if(vt == NULL)
+        return 0;
     char buff[MAXBUFF*3],*p=buff;
     int i;
     for (i=vt->cur;i<vt->n;i++) *p++=vt->buff[i];
@@ -142,6 +147,8 @@ static int ref_buff(vt_t *vt)
 /* move cursor right ---------------------------------------------------------*/
 static int right_cur(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     if (vt->cur>=vt->n) return 1;
     if (write(vt->out,vt->buff+vt->cur,1)<1) return 0;
     vt->cur++;
@@ -150,6 +157,8 @@ static int right_cur(vt_t *vt)
 /* move cursor left ----------------------------------------------------------*/
 static int left_cur(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     if (vt->cur<=0) return 1;
     vt->cur--;
     return write(vt->out,"\b",1)==1;
@@ -158,6 +167,8 @@ static int left_cur(vt_t *vt)
 static int del_cur(vt_t *vt)
 {
     int i;
+    if(vt == NULL)
+        return 1;
     if (vt->cur<=0) return 1;
     for (i=vt->cur;i<vt->n;i++) vt->buff[i-1]=vt->buff[i];
     vt->n--;
@@ -166,6 +177,8 @@ static int del_cur(vt_t *vt)
 /* insert character after cursor ---------------------------------------------*/
 static int ins_cur(vt_t *vt, char c)
 {
+    if(vt == NULL)
+        return 1;
     int i;
     if (vt->n>=MAXBUFF) return 1;
     for (i=vt->n++;i>vt->cur;i--) vt->buff[i]=vt->buff[i-1];
@@ -176,6 +189,8 @@ static int ins_cur(vt_t *vt, char c)
 /* add history ---------------------------------------------------------------*/
 static int hist_add(vt_t *vt, const char *buff)
 {
+    if(vt == NULL)
+        return 1;
     int i,len;
     if ((len=strlen(buff))<=0) return 1;
     free(vt->hist[MAXHIST-1]);
@@ -187,6 +202,8 @@ static int hist_add(vt_t *vt, const char
 /* call previous history -----------------------------------------------------*/
 static int hist_prev(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     char *p;
     if (vt->cur_h>=MAXHIST||!vt->hist[vt->cur_h]) return 1;
     if (!clear_buff(vt)) return 0;
@@ -196,6 +213,8 @@ static int hist_prev(vt_t *vt)
 /* call next history ---------------------------------------------------------*/
 static int hist_next(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     char *p;
     if (!clear_buff(vt)) return 0;
     if (vt->cur_h==0||!vt->hist[vt->cur_h-1]) return 1;
@@ -205,6 +224,8 @@ static int hist_next(vt_t *vt)
 /* handle telnet sequence ----------------------------------------------------*/
 static int seq_telnet(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     char msg[3]={C_IAC};
     
     if (vt->esc[1]==C_WILL) { /* option negotiation */
@@ -240,6 +261,8 @@ static int seq_telnet(vt_t *vt)
 /* handle escape sequence ----------------------------------------------------*/
 static int seq_esc(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     if (vt->nesc<3) return 1;
     vt->nesc=0;
     if (vt->esc[1]=='['||vt->esc[1]=='O') {
@@ -259,6 +282,8 @@ static int seq_esc(vt_t *vt)
 *-----------------------------------------------------------------------------*/
 extern int vt_getc(vt_t *vt, char *c)
 {
+    if(vt == NULL)
+        return 0;
     struct timeval tv={0,1000}; /* timeout (us) */
     fd_set rs;
     int stat;
@@ -306,6 +331,8 @@ extern int vt_getc(vt_t *vt, char *c)
 *-----------------------------------------------------------------------------*/
 extern int vt_gets(vt_t *vt, char *buff, int n)
 {
+    if(vt == NULL)
+        return 0;
     char c;
     
     buff[0]='\0';
@@ -336,6 +363,8 @@ extern int vt_gets(vt_t *vt, char *buff,
 /* put character to console --------------------------------------------------*/
 static int vt_putchar(vt_t *vt, char c)
 {
+    if(vt == NULL)
+        return 0;
     if (!vt||!vt->state) return 0;
     if (vt->logfp) fwrite(&c,1,1,vt->logfp);
     return write(vt->out,&c,1)==1;
@@ -348,6 +377,8 @@ static int vt_putchar(vt_t *vt, char c)
 *-----------------------------------------------------------------------------*/
 extern int vt_putc(vt_t *vt, char c)
 {
+    if(vt == NULL)
+        return 0;
     if (c=='\n'&&!vt_putchar(vt,'\r')) return 0;
     return vt_putchar(vt,c);
 }
@@ -359,6 +390,8 @@ extern int vt_putc(vt_t *vt, char c)
 *-----------------------------------------------------------------------------*/
 extern int vt_puts(vt_t *vt, const char *buff)
 {
+    if(vt == NULL)
+        return 1;
     const char *p;
     for (p=buff;*p;p++) if (!vt_putc(vt,*p)) return 0;
     return 1;
@@ -372,6 +405,8 @@ extern int vt_puts(vt_t *vt, const char
 *-----------------------------------------------------------------------------*/
 extern int vt_printf(vt_t *vt, const char *format, ...)
 {
+    if(vt == NULL)
+        return 1;
     va_list ap;
     char buff[MAXBUFF+1];
     va_start(ap,format);
@@ -386,6 +421,8 @@ extern int vt_printf(vt_t *vt, const cha
 *-----------------------------------------------------------------------------*/
 extern int vt_chkbrk(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     char c;
     vt->brk=0;
     return !vt_getc(vt,&c)||vt->brk;
@@ -398,6 +435,8 @@ extern int vt_chkbrk(vt_t *vt)
 *-----------------------------------------------------------------------------*/
 extern int vt_openlog(vt_t *vt, const char *file)
 {
+    if(vt == NULL)
+        return 1;
     if (!vt||!vt->state||!(vt->logfp=fopen(file,"w"))) return 0;
     return 1;
 }
@@ -408,6 +447,8 @@ extern int vt_openlog(vt_t *vt, const ch
 *-----------------------------------------------------------------------------*/
 extern void vt_closelog(vt_t *vt)
 {
+    if(vt == NULL)
+        return 1;
     if (!vt||!vt->state||!vt->logfp) return;
     fclose(vt->logfp);
     vt->logfp=NULL;


@Lankaster
Copy link

Lankaster commented Feb 1, 2022

@kme-it Hi, You patch are great, but it doesn't help to start rtkrcv completely headless: I've able to start it in terminal.
Do you have maybe another changes for new version? right now its' looks so:

--- a/app/consapp/rtkrcv/rtkrcv.c
+++ b/app/consapp/rtkrcv/rtkrcv.c
@@ -420,9 +420,11 @@
         else cmds_periodic[i]=s2[i];
     }
     /* confirm overwrite */
+    if(vt != NULL) {
     for (i=3;i<8;i++) {
         if (strtype[i]==STR_FILE&&!confwrite(vt,strpath[i])) return 0;
     }
+    }
     if (prcopt.refpos==4) { /* rtcm */
         for (i=0;i<3;i++) prcopt.rb[i]=0.0;
     }

--- a/app/consapp/rtkrcv/vt.c
+++ b/app/consapp/rtkrcv/vt.c
@@ -106,7 +106,7 @@
     int i;
     
     trace(3,"vt_close:\n");
-    
+    if(vt == NULL) {return;}
     /* restore terminal mode */
     if (!vt->type) {
         tcsetattr(vt->in,TCSANOW,&vt->tio);
@@ -121,6 +121,7 @@
 /* clear line buffer ---------------------------------------------------------*/
 static int clear_buff(vt_t *vt)
 {
+    if(vt == NULL) {return 0;}
     char buff[MAXBUFF*3],*p=buff;
     int i,len=strlen(vt->buff);
     for (i=0;i<vt->cur;i++) *p++='\b';
@@ -132,6 +133,7 @@
 /* refresh line buffer -------------------------------------------------------*/
 static int ref_buff(vt_t *vt)
 {
+    if(vt == NULL) {return 0;}
     char buff[MAXBUFF*3],*p=buff;
     int i;
     for (i=vt->cur;i<vt->n;i++) *p++=vt->buff[i];
@@ -142,6 +144,7 @@
 /* move cursor right ---------------------------------------------------------*/
 static int right_cur(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     if (vt->cur>=vt->n) return 1;
     if (write(vt->out,vt->buff+vt->cur,1)<1) return 0;
     vt->cur++;
@@ -150,6 +153,7 @@
 /* move cursor left ----------------------------------------------------------*/
 static int left_cur(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     if (vt->cur<=0) return 1;
     vt->cur--;
     return write(vt->out,"\b",1)==1;
@@ -157,6 +161,7 @@
 /* delete character before cursor --------------------------------------------*/
 static int del_cur(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     int i;
     if (vt->cur<=0) return 1;
     for (i=vt->cur;i<vt->n;i++) vt->buff[i-1]=vt->buff[i];
@@ -166,6 +171,7 @@
 /* insert character after cursor ---------------------------------------------*/
 static int ins_cur(vt_t *vt, char c)
 {
+    if(vt == NULL) {return 1;}
     int i;
     if (vt->n>=MAXBUFF) return 1;
     for (i=vt->n++;i>vt->cur;i--) vt->buff[i]=vt->buff[i-1];
@@ -176,6 +182,7 @@
 /* add history ---------------------------------------------------------------*/
 static int hist_add(vt_t *vt, const char *buff)
 {
+    if(vt == NULL) {return 1;}
     int i,len;
     if ((len=strlen(buff))<=0) return 1;
     free(vt->hist[MAXHIST-1]);
@@ -187,6 +194,7 @@
 /* call previous history -----------------------------------------------------*/
 static int hist_prev(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     char *p;
     if (vt->cur_h>=MAXHIST||!vt->hist[vt->cur_h]) return 1;
     if (!clear_buff(vt)) return 0;
@@ -196,6 +204,7 @@
 /* call next history ---------------------------------------------------------*/
 static int hist_next(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     char *p;
     if (!clear_buff(vt)) return 0;
     if (vt->cur_h==0||!vt->hist[vt->cur_h-1]) return 1;
@@ -205,6 +214,7 @@
 /* handle telnet sequence ----------------------------------------------------*/
 static int seq_telnet(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     char msg[3]={C_IAC};
     
     if (vt->esc[1]==C_WILL) { /* option negotiation */
@@ -240,6 +250,7 @@
 /* handle escape sequence ----------------------------------------------------*/
 static int seq_esc(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     if (vt->nesc<3) return 1;
     vt->nesc=0;
     if (vt->esc[1]=='['||vt->esc[1]=='O') {
@@ -259,6 +270,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_getc(vt_t *vt, char *c)
 {
+    if(vt == NULL) {return 0;}
     struct timeval tv={0,1000}; /* timeout (us) */
     fd_set rs;
     int stat;
@@ -306,6 +318,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_gets(vt_t *vt, char *buff, int n)
 {
+    if(vt == NULL) {return 0;}
     char c;
     
     buff[0]='\0';
@@ -336,6 +349,7 @@
 /* put character to console --------------------------------------------------*/
 static int vt_putchar(vt_t *vt, char c)
 {
+    if(vt == NULL) {return 0;}
     if (!vt||!vt->state) return 0;
     if (vt->logfp) fwrite(&c,1,1,vt->logfp);
     return write(vt->out,&c,1)==1;
@@ -348,6 +362,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_putc(vt_t *vt, char c)
 {
+    if(vt == NULL) {return 0;}
     if (c=='\n'&&!vt_putchar(vt,'\r')) return 0;
     return vt_putchar(vt,c);
 }
@@ -359,6 +374,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_puts(vt_t *vt, const char *buff)
 {
+    if(vt == NULL) {return 1;}
     const char *p;
     for (p=buff;*p;p++) if (!vt_putc(vt,*p)) return 0;
     return 1;
@@ -372,6 +388,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_printf(vt_t *vt, const char *format, ...)
 {
+    if(vt == NULL) {return 1;}
     va_list ap;
     char buff[MAXBUFF+1];
     va_start(ap,format);
@@ -386,6 +403,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_chkbrk(vt_t *vt)
 {
+    if(vt == NULL) {return 1;}
     char c;
     vt->brk=0;
     return !vt_getc(vt,&c)||vt->brk;
@@ -398,6 +416,7 @@
 *-----------------------------------------------------------------------------*/
 extern int vt_openlog(vt_t *vt, const char *file)
 {
+    if(vt == NULL) {return 1;}
     if (!vt||!vt->state||!(vt->logfp=fopen(file,"w"))) return 0;
     return 1;
 }
@@ -408,6 +427,7 @@
 *-----------------------------------------------------------------------------*/
 extern void vt_closelog(vt_t *vt)
 {
+    if(vt == NULL) {return;}
     if (!vt||!vt->state||!vt->logfp) return;
     fclose(vt->logfp);
     vt->logfp=NULL;


@kme-it
Copy link

kme-it commented Feb 9, 2022

Hi @Lankaster,

I am not sure if I understand you correctly. I wrote this patch so one could start this via systemd for example. This works with this patch. You could start this in terminal manually too, but then you don't need this fix. The one from sezeryalcin should work just fine.

@Lankaster
Copy link

Hi @kme-it I try to use it on OpenWrt device headless (without terminal) via init.d: https://github.com/openwrt/packages/tree/master/utils/rtklib

@kme-it
Copy link

kme-it commented Feb 9, 2022

@Lankaster
This should work then. What kind of errors are you facing?

Is it working from a terminal in an interactive mode?

@Lankaster
Copy link

@kme-it With this patch we're able to start rtkrcv from terminal manually, but "-s" option doesn't work: we can see only "Segment fault" error. Hier is strace log:

...
nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7fa682b0) = 0
nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7fa682b0) = 0
... a lot of same messages ...
nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7fa682b0) = 0
nanosleep({tv_sec=0, tv_nsec=100000000}, 0x7fa682b0) = 0
nanosleep({tv_sec=0, tv_nsec=100000000},  <unfinished ...>) = ?
+++ killed by SIGSEGV +++

@kme-it
Copy link

kme-it commented Feb 10, 2022

Hi @Lankaster, first I would try without the patch in interactive mode if the segfaults are happening there too. And after that in interactive mode with the patch, to bisect the scenario.

I am right now unsure if you might need the other patch to with the -s option or if you can skip the -s option. Maybe you should try with both patches. I don't have access to the the working instance with this setup here right now, so I can't look it up and at least right now I don't remember if my setup startet with or without the option.

The basic idea behind this patch is to disable all logging to a virtual terminal (which doesn't exist). This should be straight forward and i don't see how it might leed to a segfault.

I assume the patch applied without errors.

If not it's difficult to debug like this. A stacktrace would be nice, or if available a debugbuild with remote debugging might help too.

@gdelmondo
Copy link

Hi,
the following pull request closes the issue
#681

Regards,
Giorgio

AndreHauschild pushed a commit to AndreHauschild/RTKLIB that referenced this issue Jul 4, 2024
…-cmd-string-init

rtknavi_qt serverStart: initialize cmd strings emptry
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants