D(B)u(g)ck Hunting Season is opened!

Started by pjot, January 23, 2007, 01:39:29 AM

Previous topic - Next topic

newdep

#15
A small remark for pjot:



The linux Segmentation fault is an old bug that lays in slackware I can remember

mentioning this already back in the 8.xx release. It only happens on slackware it seems.



The Symlink is correct, you want to see the file size and not the symlink size,

althought I find no use in the size of the symlink, i want to see the file size.
-- (define? (Cornflakes))

pjot

#16
If you want to see the filesize, then query the file. The (file-info) mentions we're looking at a symlink; I find it confusing that I see a symlink with the size of the original file.



Also, symlinks can have different sizes themselves.



For the Segv, I am using Zenwalk 4.2, which is a Slackware spinoff, but still different from Slack 8. It is strange the issue appears in this distribution as well. Anyway, if Lutz cannot reproduce the problem, it will not count as a bug. :-)



Peter

Lutz

#17
Thanks Peter and Norman for the bug hunting efforts!



I will report on all of these tomorrow except for  [6]:



'file-info' since version 9.0.6 uses lstat(), previously stat(), to report on files. This means that on symbolic links file sizes are reported for the linked file not for the link itself, but the mode field shows that the path-name was for a link. The change was made because it seemed more practible to report file-zise on the linked file rthan on the link.



Lutz

newdep

#18
is this a BUG?



Lutz, I find this odd, but perhpas you can clear me up ->



(list '())

> (())



(map list '())

> ()



(map list '(0))

>((0))



(map list (dup '() 1))

> ((()))





Why does (map list '()) not return (()) but () ?
-- (define? (Cornflakes))

Lutz

#19
This is not a bug.



'map' applies a function to all members of the list and returns the list of results. Because the arguments list was empty nothing was done and the result list is empty.



Lutz

newdep

#20
Yes your right... I was thinking empty but not empty enough ;-)
-- (define? (Cornflakes))

pjot

#21
Quote
I though you already had a T-shirt? ;-)


Yes I do!! But as organizer of the Bug Hunting Season I am excluded from any price. :-)



Peter

pjot

#22
The (series) statement consumes all memory and CPU load



When we run this command:
Quote
(series 1 5 -1)


...my PC hangs. I almost had to reboot, but with some effort I could kill the newLisp process manually. The error is caused probably because the '-1' is considered to the max 64bit number?



Peter

pjot

#23
New list with homework extended with bugs found, including submitter.



[1] Repeating (pop) delivers 'not enough memory in function' (Norman)

[2] Quoted text and the 2048 limit (Norman) -> NO BUG - will be left out in future buglists

[3] The missing '-w' option when running 'newlisp -h' (Peter)

[4] Segv in daemon mode (Peter)

[5] (seek) returns any position (Peter)

[6] (file-info) identifies symlinks but does not show correct size (Peter)

[7] (file-info) hangs on PIPE files (Peter)

[8] (sequence) does not show '0.0' in float sequences counting downwards (Peter)

[9] newlisp -c -d always listens to port 0 instead of random number (Norman)

[10] (series) with negative argument hangs PC (Peter)





Now your remark on the (file-info) of symlinks.


Quote
'file-info' since version 9.0.6 uses lstat(), previously stat(), to report on files. This means that on symbolic links file sizes are reported for the linked file not for the link itself, but the mode field shows that the path-name was for a link. The change was made because it seemed more practible to report file-zise on the linked file rthan on the link.


Well, from Unix point of view I tend to not agree, because of the following reasons:

1) for Unix, symlinks are real files, and they can have different filesizes themselves

2) the newLisp programmer might be interested in these sizes if he wants to hack the filesystem, for example

3) isn't it kind of contradictory: the (file-info) reports a symlink, but shows the size of the original file?



I understand it is easy to have a common implementation for all OS's (Win32 will not have this problem), so for sake of portability you might want to leave it as it is. But probably there should be a remark about it in the manual, if you decide to keep it this way...?



To all forum readers: you are encouraged to find bugs! You can win a genuine newLisp T-shirt!



Regards

Peter

Lutz

#24
Quoteisn't it kind of contradictory: the (file-info) reports a symlink, but shows the size of the original file?


From a practical proint of view, one is probably more interested in the size of the file linked to than of the size of the link. The change in 9.0.6 was made in response to a user who primarily is not a programmer. This kind of user tends to see programming more from an applicative kind of perspective, which is a good thing according to newLISP's philosophy.



I am almost done dealing with your list and will post fixes and comments later today.



Lutz

Lutz

#25




[1] Repeating (pop) delivers 'not enough memory in function' (Norman)

[2] Quoted text and the 2048 limit (Norman) -> NO BUG - will be left out in future buglists

[3] The missing '-w' option when running 'newlisp -h' (Peter)

[4] Segv in daemon mode (Peter)

[5] (seek) returns any position (Peter)

[6] (file-info) identifies symlinks but does not show correct size (Peter)

[7] (file-info) hangs on PIPE files (Peter)

[8] (sequence) does not show '0.0' in float sequences counting downwards (Peter)

[9] newlisp -c -d always listens to port 0 instead of random number (Norman)

[10] (series) with negative argument hangs PC (Peter)









[1] fixed in 9.0.19

string pops on empty strings will return ""



[2] not a bug

zero's in [text][/text] delimited do not get displayed, but the buffer is set correctly



[3] fixed in 9.0.19

missing options will show up in help



[4] cannot repeat on some platforms

on Mac OSX, FreeBSD and Solaris I cannot repeat this problem, on these platforms I get correctly a "(c)ontinue, (d)ebug, e(x)it, (r)eset" when hitting Ctrl-C. I wonder if the problem on Slackware is related to signal handling or an invalid socket handle? can you check using systrace or a similar tool.



[5] not a bug

This is the way its supposed to be, for creating sparse files in "update" mode: from the docs of GCC:



lseek can set the file position past the current end of the file. This does not by itself make the file longer; lseek never changes the file. But subsequent output at that position will extend the file. Characters between the previous end of file and the new position are filled with zeros. Extending the file in this way can create a "hole": the blocks of zeros are not actually allocated on disk, so the file takes up less space than it appears to; it is then called a "sparse file".



I will add something like above for 'seek' in the manual.



[6] not a bug

see changes notes for 'file-info' in 9.0.6 and discussion (will add more info in manual)



[7] fixed in 9.0.19

will return zero size for named pipes



[8] not a bug

hits rounding error at 16 digits of precision for double floats in binary/decimal conversion



[9] fixed in 9.0.19

starting server mode with no port number or 0 will fail



[10] fixed in 9.0.19

four counts < 1 'series' will return an empty list



Version 9.0.19 will be released on coming Monday



Lutz

pjot

#26
Hi Lutz,



Thanks for your 9.0.19 release! And it sure is no list of shame. We all profit from improvements.



Also, in spite of my busy activities during this weekend, I could not resist looking at the SEGV problem. :-)



Also with 9.0.19 this problem occurs.



Resume: start newLisp in daemon mode.
Quote
peter[~]$ newlisp -c -d 8080


From another terminal, telnet to port 8080. Then press the standard '<CTRL> ]' and then 'q' to quit the telnet connection again.
Quote
peter[~]$ telnet localhost 8080

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

^]



telnet> q

Connection closed.

peter[~]$


Go back to the first terminal and press <CTRL>+C to quit the newLisp daemon.
Quote
peter[~]$ newlisp -c -d 8080

Segmentation fault

peter[~]$


Now, with the wonderfull VALGRIND tool, I was able to trace back the cause of this problem. There is an invalid READ in your 'newlisp.c' at line 1965.

fprintf(IOchannel, "%s", buffer);


The problem is with the variable 'buffer',  for which no memory is allocated. Indeed, the function 'varPrintf' does not allocate this variable at all! When I bruteforcefully change the code as follows:

1929 void varPrintf(UINT device, char * format, ...)
1930 {
1931 char * buffer;
1932 va_list argptr;
1933
1934 va_start(argptr,format);
1935
1936 /* new in 7201 , defined in nl-filesys.c if not in libc */
1937 buffer = (char*)malloc(sizeof(char)*1024); <------!!!!
1938 vasprintf(&buffer, format, argptr);
1939


...the problem is gone. As you can see, I allocate 1024 bytes. But I am not sure how large this allocation must be. However, if I change the code like this, the SEGV problem is gone.



I will verify your other fixes later and come back to you ASAP.



Cheers

Peter

Lutz

#27
The function vasprintf() is supposed to allocate the memory. Probably the implementation of vasprintf() on the Linux distribution is not to the spec of GCC.



Do the following in newlisp.h



#ifdef LINUX

#define vasprintf my_vasprintf

#define MY_VASPRINTF

#endif



The same is done already for OS2, MAC_OSX, SOLARIS and WINCC. Only the vasprintf() on FreeBSD seems to work as prescribed by the GCC docs. vasprintf() should allocate the memory for the buffer which then is freed by the user.



The above #ifdef should solve the problem using newLISP's own definition of vasprintf(), my_vasprintf() in nl-filesys.c.



Unfortunately the implementation of my_vasprintf() hits another frequent problem with the implementation in different compilers of vsnprintf(). Ther are further #ifdef in the my_vasprintf() for this, which at the moment distinguish between MINGW, TRU64 and anything else. LINUX should then fall into one of both groups.



Unfotunately I cannot repeat this problem to debug it myself but probably the #ifdef in newlisp.h alone will solve it, if not you might have to add:



#if defined(MINGW) || defined(TRU64) || defined(LINUX)



int the definition of myvasprintf() in the file nl-filesys.c



thanks for checking



Lutz

pjot

#28
Good morning,



I have tried your macro workaround, but the same problem occurs. I even hardcoded 'vasprintf' to 'my_vasprintf' to make sure the function was entered and the result was the same (segfault).



The returnvalue from 'vasprintf' was equal to 'my_vasprintf'. It seems the memory for the buffer is allocated properly then.



Therefore I restored everything and checked valgrind again. The error occurs at line 1965 in 'newlisp.c':

1965 fprintf(IOchannel, "%s", buffer);


Instead of looking at buffer, I changed the variable IOchannel to 'stdout'. This also solved the segfault: I receive the default message on the console when pressing <CTRL>+<C>, presumably the correct output.



When I put the following code just before this line:

printf("Return: %sn", strerror(errno));
fflush(stdout);


...the warning 'bad filedescriptor' appears.



Looking through your code it seems you are using 'IOchannel' also for the daemon mode. Can it be that there is a problem with this filedescriptor? For with a <CTRL>+<C> you want to write a default message to the console, while at the same time this filedescriptor is in use for the newLisp daemon.



Regards

Peter

Lutz

#29
Tha bad filedescriptor in the Ctrl-C handler is definetly the reason. The descriptor gets invalid when the connection closes when telnet is quitted.  The Ctrl-C handler always should write to stdout or stderr, I can change that.



Thanks for chasing this down



Lutz