Bug in g_strjoin



I cannot get g_strjoin in to behave properly. I am using glib 1.1.9. The
bug is either the way g_strjoin calls va_start twice within the same
function, or is a faulty implementation of <stdargs.h> by gcc, egcs, and
the SGI compiler.

On some platforms, my first call to g_strjoin will work fine, but fail
the next time. Failure can either be a segfault, or the joining of too
many strings.  For example, If I say g_strjoin(".", "tr", "sr"), I'll
get "tr.sr.tr.sr". I have verified with gdb that va_arg is passing bad
or extra pointers to the while loop inside of g_strjoin.
 On other platforms, even the first call to g_strjoin fails.

To test the va_arg behavior, I made a small program which calls g_strjoin
twice. I put the code to g_strjoin in this small program and un-glibbed it
so that I could compile it on platforms where I don't have glib. But you'll
see that it's the same g_strjoin code. I put some debugging printf
statements in it, but the behavior is the same without these printf
statements.

Here's my test program.
------------------------------------------
#include <stdarg.h>
#include <stdio.h>

char*
g_strjoin (const char  *separator,
	   ...)
{
  char *string, *s;
  va_list args;
  int len;
  int separator_len;

  if(separator == NULL)
    separator = "";

  separator_len = strlen (separator);

  va_start(args, separator);

  s = va_arg(args, char *);
  printf("\tstep0: found %s\n", s);

  if(s) {
    len = strlen(s) + 1;

    while((s = va_arg(args, char*)))
      {
		  printf("\tstep1: found %s\n", s);
		len += separator_len + strlen(s);
      }
    va_end(args);

    string = (char*)malloc (len);

    va_start(args, separator);

    *string = 0;
    s = va_arg(args, char*);
  printf("\tstep2: found %s\n", s);
    strcat (string, s);

    while((s = va_arg(args, char*)))
      {
		  printf("\tstep3: found %s\n", s);
	strcat(string, separator);
	strcat(string, s);
      }

  } else {
    /*string = strdup("");*/
	  string = (char*)malloc(1);
	  string[0] = 0;
	 }

  va_end(args);

  return string;
}

int main(void)
{
	char *str = NULL;

	str = g_strjoin(".", "tr", "sr");
	printf("g: %s\n", str);

	str = g_strjoin(".", "tr", "sr");
	printf("g: %s\n", str);

	return 0;
}
----------------------------------------------------

I *should* get:

	step0: found tr
	step1: found sr
	step2: found tr
	step3: found sr
g: tr.sr
	step0: found tr
	step1: found sr
	step2: found tr
	step3: found sr
g: tr.sr

I don't. Here's the output for the platforms I have access to:

Irix 6.2, MIPS, SGI C compiler
==============================
        step0: found tr
        step1: found sr
        step1: found
+>RZo
|
0Ef
        step2: found tr
        step3: found sr
        step3: found
+>RZo
|
0Ef
g:
tr.sr.+>RZo|

0Ef
        step0: found tr
        step1: found sr
        step2: found tr
        step3: found sr
g: tr.sr                   

Linux 2.0.36, Pentium II, gcc 2.7.2.3
=====================================
        step0: found tr
        step1: found sr
        step2: found tr
        step3: found sr
g: tr.sr
        step0: found tr
        step1: found sr
        step1: found tr.sr
        step2: found tr
        step3: found sr
        step3: found tr.sr
g: tr.sr.tr.sr 

Linux 2.0.33, Pentium II, gcc 2.7.2.1
=====================================
        step0: found tr
        step1: found sr
        step2: found tr
        step3: found sr
g: tr.sr
        step0: found tr
        step1: found sr
        step1: found tr.sr
        step1: found
        step1: found Pdt&
Segmentation fault (core dumped)     

AIX 4.1.5, RS/6000, gcc 2.7.2.1
===============================
        step0: found tr
        step1: found sr
        step1: found
        step1: found
        step2: found tr
        step3: found sr
        step3: found
        step3: found
g: tr.sr..
        step0: found tr
        step1: found sr
Segmentation fault (core dumped) 

Linux 2.0.35, SPARC, egcs-2.90.27 980315 (egcs-1.0.2)
=====================================================
        step0: found tr
        step1: found sr
        step1: found  
        step1: found
Segmentation fault (core dumped) 

Solaris 2.6, UltraSPARC, gcc 2.8.1
==================================
        step0: found tr
        step1: found sr
        step1: found 
        step1: found
        step1: found @)"
        step1: found 
Segmentation Fault (core dumped) 


At first I thought it was a bug in gcc, but with the behavior of the SGI
compiler, I no longer know what to think. Any ideas?

--gilbert

-- 
Gilbert Ramirez                Voice:  +1 210 358 4032
Technical Services             Fax:    +1 210 358 1122
University Health System       San Antonio, Texas, USA



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]