the horrors

Document Sample
the horrors Powered By Docstoc
					The horrors
Nezer (T.A) and Evyatar (Bodek)
        This ex – what we learned
                   planned                                  For some of you
   Stream sockets – TCP                                vi or other unix editors
   Stream sockets – UDS
                                                        make/makefile
   Select, blocking and non blocking system calls
                                                        Debugging code in UNIX (gdb/ddd and
   fork(2)
                                                         core dumps)

   syslog(3)                                           Opendir/readdir/dirent

   getenv(3)                                           grep(1) and other basic UNIX functions
   time(2)
                                                        Strace(1)
   signal(3)/sigaction(2)
                                                        Working on schedule
   waitpid(2)
                                                        Ps(1)/kill(1) etc.
    Some of you were lucky….
 The lucky encountered enough bugs to learn something….

 (The extremely lucky ones lost sleep over some of the
  bugs so they will remember them!)

 This is a collection of common errors we encountered for
  the less fortunate ones

 We also bring some style errors so you can learn for future
                     Busy waiting
          The code                    Better ways to act
 (timeToRun>time(null) ;        sleep(TimeToSleep); // or


                                pause(); // or

// that is call time infinite   struct timeval tv;
    number of times             tv.tv_sec=TimeToSleep;


                                select (1, MULL, NULL, NULL, &tv);
       The chicken and the egg
What comes first > or =?
If (pid = fork() < 0)….

How it should be done
If ((pid = fork()) < 0)

< is calculated before =!!!
    Logical assumptions and checking
               error codes
A team comes to me with the following      After de-mysitification….
                                           1. UNIX doesn’t hate them
   They didn’t change the server
                                           2. The server crashes
   The server used to work
                                           After further investigation we found the
   Now the server does not appear in          crash in following line
                                           Myport = atoi(getenv(“My port”));
   It also doesn’t accept clients

   Reaching the only logical conclusion
                                           What lesson have we learned?
   The server becomes invisible

   And UNIX hates them
             The OS is my bitch 1
       Fopen mania          How it should be done
x=fopen (“log.txt”,”a”);    At main start :
fprintf(x,”something”);      fopen/fopen
fclose(x);                  Each time we log we
// some lines later          write/fprint (and possible
x=fopen (“log.txt”,”a”);
                            At finish we fclose/close
        The OS is my bitch 2
    Stupid sleeping           What is wrong
While                     sleep the time difference
 sleep(1)                 Don’t use magic numbers

                          No points were deducted
                           for this (this is not busy
                           waiting, just stupid)
           Garbage is my friend
Some of you just had to :
Send (sockfd, buf, 100, 0)

Resulting in sending 100-
  strlen(buf) bytes of

Unlucky perhaps but the
  garbage also contained null
  so your printing didn’t
  detect it
 Using buffers returned by
  dirent structure is perfectly
  legal…. Yet some of you had
  to copy everything to YOUR
  OWN buffer…..
 Some of you even malloced
  the buffer and freed it at
  every iteration
 Some of you forgot to free
 Unless there was also no
  free no points were
The peak
      Not even 8.3            How it should work
Memcpy(buf,dp->name,10);    Use original dirent data.
                             (no need to copy)
                            Use dirent struct to tell
                             you how much to send
Some things just hurt our eyes
 Functions should be
  described in one
  sentence with no and/or.

 If you can’t describe your
  functions with one
  sentence – break them to
        How to learn something new!
           THE KISS METHOD
 Don’t automatically start with a huge program because if it
  breaks you can’t figure how and why!
 Understand from book/man page what you want to do.
 Write a small test case for each new system call you learn. –
  make the test case work.
 Make sure you understand how it works then integrate in your
  main code!
 When all else fails…. RTFM = read the fucking friendly
               Common errors
 Daemon process under SVR4 UNIX (Linux, Solaris, HP-UX)
  need to fork() twice. (13.3 Advanced programming in the
  UNIX environment.)

 For those that seen other sources in the internet: Daemon
  process under BSD UNIX (xxxBSD, OSX, AIX) can fork()
  only once. (but forking twice is not a mistake)

 Environment parameters ARE NOT command line
  argument. (read the UNIX process presentation)

 UDS socket was relative path name. (./smt) this will fail if
  the client is run from different directory! Use absolute path
  (/tmp/smt or ~/smt) to avoid this.
             Using Syslog in TAU
/* works between processes (such as between bzip and main
   thread in the ex. Not between threads) */

Int main()


    openlog(“scipio”, 0, LOG_LOCAL5);

    syslog(LOG_ERR, “%s, %d : hello world”, __FILE__,


       Fcntl file locking example
#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <fcntl.h>

#include <unistd.h>

int main(int argc, char *argv[])


                                /* l_type l_whence l_start l_len l_pid */

                      struct flock fl = { F_WRLCK, SEEK_SET, 0, 0, 0 };
    Fcntl example cont’d
      int fd;

      fl.l_pid = getpid();

      if (argc > 1) fl.l_type = F_RDLCK;

      fd = open("lockdemo.c", O_RDWR)

      fcntl(fd, F_SETLKW, &fl);

      fl.l_type = F_UNLCK;

      fcntl(fd, F_SETLK, &fl) ;


                           GCC versions
Char s[200];


In tau that returns 200;

We have tried on other servers and since sizeof char *=4 and char [] is actually char*….
   That returned 4.

To avoid problems in the future don’t do sizeof array but sizeof (element) * array size.

No points were deducted.

(Evyatar apologizes for causing several undue heart attacks).
          Request from System
 Avoid running your jobs on NOVA if you can

 You are
   Running lots of jobs
   Busy waiting
   Taking all the CPU

 Instead once you login, ssh to any doppler or Euler workstation and
  work there.

 NOVA is the only host accessible from outside TAU. So if you login to
  NOVA and load it with unbearable load you are screwing your fellow
 Don’t wait for the last minute to submit the ex.

 Check your timeouts. NOVA was very stable during the ex.
  Submission but also very loaded and several students
  failed to login due to short timeouts
  & Rago (chapters 4,7,8,9,10,13,14,(15 = bonus), 16, 17 were covered in
  ex. 1 + chapters 3+8+10+11+12+14 are covered in ex. 2)
 KR (The C programming language – Brian Keringhan and Dennis
Other good books
 Solaris System programming / Rich teer (run the examples to make
  sure they work on Linux as well) 1,4,6,10,13,14,15,16,17,18,19,21 –
  Almost identical arrangement to Stevens with some Solaris specific
 Advanced UNIX programming (Warren W. Gay) 1-7, 9-11, 15-19,22,26
                      The Cost
 send(3) with fixed buflen parameter: -3
 Segmentation fault when running client with missing/no
  parameters: -5
 UDS only connects when client and server are in the same
  folder: -10
 Sending only 10 chars of file name. -10
 Not using environment variables at all: -10
 Using printf() in the server daemon: -2
 Having us kick-start your project (i.e. project that would
  crash) – variable
                       More cost
 Not printing daemon getppid(): -10 (first line
  in the server description!)

 Not setting the session ID and letting me
  use ctrl+c to kill your server: -10

 Client hangs on a past/illegal time index: -5

 Server crashes when UDS connects: -30

 Not logging to syslog() OR file: -10

 Not running as Daemon at all. -20

 Not logging child termination: -10
                 A Silver Lining
 Leaving defunct processes (zombies): just a warning

 Printing getpid() instead of getppid(): just a notice

 Non-functional FIFO with effort: +[1,9]

 Doing well on the oral exam: +[1,10]
 With the exception of one team (who had some problems)
  all teams submitted on time.

 AVG grade was about 85.

 No students that was tested Wednesday copied his work in
  our opinion

 Most students were very successful in the oral exam.
  (nobody was mistaken in more then 1 question. And 1 was
                       Regarding ex. 2
 Here is what I meant for you to do

1. I am a thread

2. The file to be sent is X, last position sent was Y, chunk size is Z

3. If the file isn't locked:

  3.1. lock

  3.2 create chunk from Y to Y+Z

  3.3 Increase Y by Z

  3.4 Release lock

  3.5 send (Send can also be done in 3.2 but this is more accurate)

Thanks to Dor Levi that put it clear.
             Defining protocol
 If you want to support only 1 client you only need to define
  the last packet and the packet number (As they may arrive
  out of order). You may want to transfer the filesize and
  offset instead.

 If you want to support several clients you need to add
  mutex for file name received (or to start different set of
  connection handling threads for each client, with different
  conds) and make sure files don’t overwrite each other.

 Exact design it up to you. You may use temp files but you
  have to clean your work
 While it is possible to do no syncing AT ALL (this ex. Can
  work even as single thread sending or compressing. (since
  we work on the same host no sending is even necessary)

 BUT you are required to sync the file reading and sending

Shared By: