Time & date & other - libc/dietlibc/uclibc/musl difference

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

Time & date & other - libc/dietlibc/uclibc/musl difference

#1 Post by goingnuts »

I have noticed that when I use uclibc or dietlibc I get a different time than when using normal libc. The below c-code can be compiled by:
"gcc show_time.c -o show_time" or "diet gcc show_time.c -o show_time"

Code: Select all

//gcc show_time.c -o show_time
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
  time_t now;
  time(&now);
  printf("%s", ctime(&now));
  return EXIT_SUCCESS;
}
When running the libc-compiled bin I get:
Sat Sep 29 14:39:24 2012
which is in many ways the result I want...but running the same bin linked with dietlibc or uclibc gives:
Sat Sep 29 06:40:38 2012
which is not the time I want...
How to fix this?
Last edited by goingnuts on Thu 07 Mar 2013, 19:46, edited 1 time in total.

User avatar
Karl Godt
Posts: 4199
Joined: Sun 20 Jun 2010, 13:52
Location: Kiel,Germany

#2 Post by Karl Godt »

No idea . It seems that the 8 hours difference might be related to the kernel compiled in GMT-8 (PERTH (actually is +8 ) -usual Puppy Bogus) back then . Dunno how the other compiles do work, but probably it is in the non-standard headers .

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#3 Post by goingnuts »

Thanks Karl - you are right - normal libc build shows the systemtime (which I want) but the dietlibc and uclibc shows the adjusted time if timezone are chosen. If I set timezone to GMT they show the same (the /etc/localtime symlink). After changing timezone one has to reboot to get the new values from dietlibc/uclibc linked bin. Now the main issue is how to get uclibc/dietlibc to show systemtime always....

User avatar
Karl Godt
Posts: 4199
Joined: Sun 20 Jun 2010, 13:52
Location: Kiel,Germany

#4 Post by Karl Godt »

bash-3.00#

Code: Select all

diff /opt/diet/include/time.h /usr/include/time.h |wc -l
488
I could think of replacing the header(s) ?

* BTW : This musl thread is quite good . I followed the simple instructions and was able to build a working guess_fstype for my kernel, that diet could not .

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#5 Post by goingnuts »

musl is looking very promising! I still havent been able to compile a working gtk1.2 so not using it intensive yet...
I can compile "guess_fstype_withext4_test1" with diet gcc by the following command:
diet gcc -D_BSD_SOURCE -s -Os guess_fstype.c main.c -o guess_fstype
ends up in a 17K bin.

As for the time issue I havent made progress. I thought that maybe the uclibc/dietlibc was using the global variable $TZ but they are not.

Did a strace on the bins - this indicate that they use the same value for the calculation. Btw. looking at the output of strace is quite interesting: The libc linked bin is doing a lot of things that seems irrelevant:

Code: Select all

access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2", 0xbf9607dc) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686", 0xbf9607dc)     = -1 ENOENT (No such file or directory)
open("/lib/tls/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/sse2", 0xbf9607dc)     = -1 ENOENT (No such file or directory)
open("/lib/tls/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file or directory)
stat64("/lib/tls", 0xbf9607dc)          = -1 ENOENT (No such file or directory)
open("/lib/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/i686/sse2", 0xbf9607dc)    = -1 ENOENT (No such file or directory)
open("/lib/i686/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
stat64("/lib/i686", 0xbf9607dc)         = -1 ENOENT (No such file or directory)
open("/lib/sse2/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
stat64("/lib/sse2", 0xbf9607dc)         = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
Why does it have to sort of "guess" the location of libc.so.6? Must slow down every binary we start...

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#6 Post by Ibidem »

goingnuts wrote:musl is looking very promising! I still havent been able to compile a working gtk1.2 so not using it intensive yet...
IIRC, it was basically just that __(u)int{,8,16,32}_t needs to be defined/changed to (u)int{,8,16,32}_t.
-D__uint32_t=uint32_t -D__int32_t=int32_t or

Code: Select all

sed -e 's/__\(u*int[123468]*_t\)/\1/g' -i <filename>
The issue is that someone didn't bother setting the right feature test macros/standards and just used the internal aliases instead.
I can compile "guess_fstype_withext4_test1" with diet gcc by the following command:
diet gcc -D_BSD_SOURCE -s -Os guess_fstype.c main.c -o guess_fstype
ends up in a 17K bin.

As for the time issue I havent made progress. I thought that maybe the uclibc/dietlibc was using the global variable $TZ but they are not.
How'd you find this out?
note that TZ=XXX only affects timezone displayed; you need to set at least
TZ=XSTn[XDT(n-1)]
POSIX specifies the "n" as the value that needs to be added to localtime to get UTC.
In other words, for Perth you should use
TZ=WST-8
and California/PDT:
TZ=PST8PDT7
Did a strace on the bins - this indicate that they use the same value for the calculation. Btw. looking at the output of strace is quite interesting: The libc linked bin is doing a lot of things that seems irrelevant:

Code: Select all

access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686/sse2", 0xbf9607dc) = -1 ENOENT (No such file or directory)
open("/lib/tls/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/i686", 0xbf9607dc)     = -1 ENOENT (No such file or directory)
open("/lib/tls/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/tls/sse2", 0xbf9607dc)     = -1 ENOENT (No such file or directory)
open("/lib/tls/libc.so.6", O_RDONLY)    = -1 ENOENT (No such file or directory)
stat64("/lib/tls", 0xbf9607dc)          = -1 ENOENT (No such file or directory)
open("/lib/i686/sse2/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/lib/i686/sse2", 0xbf9607dc)    = -1 ENOENT (No such file or directory)
open("/lib/i686/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
stat64("/lib/i686", 0xbf9607dc)         = -1 ENOENT (No such file or directory)
open("/lib/sse2/libc.so.6", O_RDONLY)   = -1 ENOENT (No such file or directory)
stat64("/lib/sse2", 0xbf9607dc)         = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY)        = 3
Why does it have to sort of "guess" the location of libc.so.6? Must slow down every binary we start...
The theory is ostensibly that you can get an "optimized" libc for your system; as usual with glibc, it slows everything down 8)

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#7 Post by technosaurus »

to fix time warps when compiling

Code: Select all

for x in `find .`; do touch $x;done
Bonus: here is some C to give you elapsed time (replace sleep with your commands) ... because you can't time part of your code with the time command

Code: Select all

#include <sys/time.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
 
int main(void){
struct timeval tim;
double started, stopped;
gettimeofday(&tim, NULL);
	started = (double) (tim.tv_sec * 1000000 + tim.tv_usec);
sleep(1);
gettimeofday(&tim, NULL);
	stopped = (double) (tim.tv_sec * 1000000 + tim.tv_usec);
return (printf("DELTA=%.6lf", (float) (stopped - started)/1000000));
}
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#8 Post by goingnuts »

Ibidem: The gtk1.2 build ok but exits when trying to run bins linked against the libs with the error:
GLib-ERROR **: could not allocate -1 bytes
aborting...
Aborted
valgrind/gdb gives no clue (to me) but the error seems to come from function g_malloc0 in gmem.c (glib-1.2.10) at:

Code: Select all

p = (gpointer) calloc (size, 1);
  if (!p)
    g_error ("could not allocate %ld bytes", size);
which tells me ...nothing...

As for the thought that TZ was used it was just a wild guess as the difference matched the last digits in TZ. Found that dietlibc, uclibc and musllibc all gives the same time running the show_time program (the timezone modified time) whereas libc gives the system time...

technosaurus: thx for the elapsed time coding.

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#9 Post by technosaurus »

GLib-ERROR **: could not allocate -1 bytes
aborting...
Aborted
I ran into that problem when I was building my musl+gtk1 toolchain - eventually got it to build, but I don't remember how, just that it involved a lot of google... then again I ended up commenting out a lot of stuff until the title bar always ended up empty on localized programs.
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#10 Post by goingnuts »

Just a follow up on musl/glib-1.2.10 problem: Compiled musl-0.9.9 and glib-1.2.10 with -g and run the testglib binary coming with glib. glib is compiled with -DENABLE_MEM_CHECK to get it a little further than

Code: Select all

GLib-ERROR **: could not allocate -1 bytes
aborting...
Aborted 
With gdb I get:

Code: Select all

Starting program: /mnt/sdc3/musl-toolchain/build/glib-1.2.10/testglib 
TestGLib v1.2.10 (i:10 b:10)
cwd: /mnt/sdc3/musl-toolchain/build/glib-1.2.10

Program received signal SIGSEGV, Segmentation fault.
0xb7eefc95 in memset (dest=0x805d128, c=0, n=4294881575)
    at src/string/memset.c:17
17                      for (w = (void *)s; n>=SS; n-=SS, w++) *w = k;
(gdb) backtrace
#0  0xb7eefc95 in memset (dest=0x805d128, c=0, n=4294881575)
    at src/string/memset.c:17
#1  0x0804f27a in g_free (mem=0x805d120) at gmem.c:409
#2  0x0805916e in g_get_any_init () at gutils.c:549
#3  0x0805925e in g_get_user_name () at gutils.c:595
#4  0x08049d4f in main () at testglib.c:352
I guess its not memset but maybe the value passed to it?
If I change the code in testglib.c like below

Code: Select all

//g_print ("user: %s\n", g_get_user_name ());
char *p=getenv("USER");
g_print ("user: %s\n", p);
then it works but fail at next call with same error:

Code: Select all

TestGLib v1.2.10 (i:10 b:10)
cwd: /mnt/sdc3/musl-toolchain/build/glib-1.2.10
user: root

Program received signal SIGSEGV, Segmentation fault.
0xb7f01c95 in memset (dest=0x805d148, c=0, n=4294881607)
    at src/string/memset.c:17
17                      for (w = (void *)s; n>=SS; n-=SS, w++) *w = k;
(gdb) backtrace
#0  0xb7f01c95 in memset (dest=0x805d148, c=0, n=4294881607)
    at src/string/memset.c:17
#1  0x0804f288 in g_free (mem=0x805d140) at gmem.c:409
#2  0x0805917e in g_get_any_init () at gutils.c:549
#3  0x0805930d in g_get_real_name () at gutils.c:606
#4  0x08049d75 in main () at testglib.c:356
...what is wrong in there?
Update: Kind of knew posting here would help...
So went into the g_get_any_init function and commented along the way. Configure sets #define HAVE_PWD_H 1 in config.h which seem to get g_get_any_init off the track. If eliminated after configure it just - runs :D

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#11 Post by Ibidem »

FYI, you can avoid the edit after configure by setting the environment variable ac_cv_header_pwd_h=0 before you run configure.

Also, a note: original glib 1.2.10 needs G_GNUC_PRETTY_FUNCTION to not be set to __PRETTY_FUNCTION__ for gcc 4.x; this is because gcc 4.x defines this to a variable not a string constant. There are probably patches that address this already.

Another note: I'm finding that gtk 1.2 needs X_EXTRA_LIBS="-lXext" here, or the libX11 test will fail.

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#12 Post by goingnuts »

After further testing I found that it is actually the HAVE_GETPWUID_R that needs to be disabled - then "user/real user" is correctly "root/root" and not "somebody/Unknown".
And setting "ac_cv_func_getpwuid_r=0" works - thanks for the tip!

Debian has a patch for gtk (glib1.2_1.2.10-19build1.diff) that handles the G_GNUC_PRETTY_FUNCTION.

Having a working musl-glib-1.2.10 wont give an error free musl-gtk-1.2.10 - I still have issues with menus being micro-sized and without label and the fileselect segfaults somewhere in strcmp. But its a start!

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#13 Post by Ibidem »

goingnuts wrote:After further testing I found that it is actually the HAVE_GETPWUID_R that needs to be disabled - then "user/real user" is correctly "root/root" and not "somebody/Unknown".
And setting "ac_cv_func_getpwuid_r=0" works - thanks for the tip!

Debian has a patch for gtk (glib1.2_1.2.10-19build1.diff) that handles the G_GNUC_PRETTY_FUNCTION.

Having a working musl-glib-1.2.10 wont give an error free musl-gtk-1.2.10 - I still have issues with menus being micro-sized and without label and the fileselect segfaults somewhere in strcmp. But its a start!
Any chance of a testcase for getpwuid_r? If there's a bug, it needs fixing; but "an ancient version of glib doesn't work right" is pretty bad for tracking it down.
Also the strcmp segfault sounds like a problem.

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#14 Post by goingnuts »

Further test: Seems that the below hack (setting bufsize = 64) in gutils.c enable build without the disabled ac_cv_func_getpwuid_r. So for some reason the sysconf(_SC_GETPW_R_SIZE_MAX) fails...seems to be set to 70...so is it the sysconf who is failing?

Debug is (kind of) fun...

in function g_get_any_init:

Code: Select all

ifdef _SC_GETPW_R_SIZE_MAX  
        /* This reurns the maximum length */
      //  guint bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
        guint bufsize = 64;
#    else /* _SC_GETPW_R_SIZE_MAX */
        guint bufsize = 64;
#    endif /* _SC_GETPW_R_SIZE_MAX */

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#15 Post by Ibidem »

goingnuts wrote:Further test: Seems that the below hack (setting bufsize = 64) in gutils.c enable build without the disabled ac_cv_func_getpwuid_r. So for some reason the sysconf(_SC_GETPW_R_SIZE_MAX) fails...seems to be set to 70...so is it the sysconf who is failing?
It actually returns -1, which explains the errors.
See http://git.musl-libc.org/cgit/musl/tree ... /sysconf.c, line 85.

This actually is mentioned in the standard:
http://pubs.opengroup.org/onlinepubs/96 ... pwnam.html
Debug is (kind of) fun...

in function g_get_any_init:

Code: Select all

ifdef _SC_GETPW_R_SIZE_MAX  
        /* This reurns the maximum length */
      //  guint bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
        guint bufsize = 64;
#    else /* _SC_GETPW_R_SIZE_MAX */
        guint bufsize = 64;
#    endif /* _SC_GETPW_R_SIZE_MAX */
The proper fix would be to change bufsize (to 1024, per the standard's example; or to _SC_GETPW_R_SIZE_MAX) if it is -1.

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#16 Post by goingnuts »

yeah - and also why dietlibc works (_SC_GETPW_R_SIZE_MAX is not defined) and also uclibc might be excused - from uclibc changelog.full:
PatchSet 3412 (...)Cleanup a few of the more egregiously broken sysconf values to
actually match reality. In particular, _SC_GETPW_R_SIZE_MAX and
_SC_GETGR_R_SIZE_MAX were causing us problems with programs such
as libglib, since they were always returning -1, which is a bit
smaller than the actual passwd and group max buffer sizes.
and from uclibc sysconf.c
/* If you change these, also change libc/pwd_grp/pwd_grp.c to match */
#define PWD_BUFFER_SIZE 256
#define GRP_BUFFER_SIZE 256
case _SC_GETGR_R_SIZE_MAX:
return GRP_BUFFER_SIZE;

case _SC_GETPW_R_SIZE_MAX:
return PWD_BUFFER_SIZE;
I will just patch the glib to set buffer to 1024.
Further progress: Got me a chroot-musl-toolchain to secure nothing sneaks in...now gtk-1.2.10 is almost there. The missing labels are caused in "gdk_set_locale" but I haven't spotted the true cause yet. Bypassing that gives working applications. Fileselect works now but I still have segfaults in textwidget - but that might actually point to the cause for apps like beaver which crash at copy from app2app...

Eventually I hope to get back to deal with time & date differences - kind of got off track lately :)

Ibidem
Posts: 549
Joined: Wed 26 May 2010, 03:31
Location: State of Jefferson

#17 Post by Ibidem »

goingnuts wrote: I will just patch the glib to set buffer to 1024.
Further progress: Got me a chroot-musl-toolchain to secure nothing sneaks in...now gtk-1.2.10 is almost there. The missing labels are caused in "gdk_set_locale" but I haven't spotted the true cause yet. Bypassing that gives working applications. Fileselect works now but I still have segfaults in textwidget - but that might actually point to the cause for apps like beaver which crash at copy from app2app...

Eventually I hope to get back to deal with time & date differences - kind of got off track lately :)
http://www.etalabs.net/compare_libcs.html says:
POSIX localedef: no
ie, it's probably a stub you encountered...Ah, src/locale/setlocale.c says this:

Code: Select all

char *setlocale(int category, const char *locale)
{
	/* Note: plain "C" would be better, but puts some broken
	 * software into legacy 8-bit-codepage mode, ignoring
	 * the standard library's multibyte encoding */
	return "C.UTF-8";
}
So what do you do to "bypass" gdk_set_locale...I presume comment out references or make it a NOP?

The main issue for times is that TZ is all musl uses; /etc/zoneinfo is what glibc uses. The plan is to change this--sometime.

goingnuts
Posts: 932
Joined: Sun 07 Dec 2008, 13:33
Contact:

#18 Post by goingnuts »

Thx! The return of "C.UTF-8" no matter what I did was puzzling...
To bypass I added:

Code: Select all

if (! strcmp (setlocale (LC_ALL, NULL), "C.UTF-8")) {return; } //musl fix
in start of gdk_set_locale in gdkim.c
The copy/paste can be "solved" by changing line in gdkselection.c/gdk_string_to_compound_text

Code: Select all

#if 0	//musl fix or tinyxlib fixme...
  g_assert (property.encoding == gdk_atom_intern ("COMPOUND_TEXT", FALSE) && property.format == 8);
#endif
...but that might be a general fix as for the first time a copy/paste from one beaver to another beaver - WORKS!

Post Reply