http://qs321.pair.com?node_id=875437


in reply to Program Hangs

Hi anbarasans85,

Seconded what ww said.

You might be able to narrow down the point where the program is stuck by trapping the INT (interrupt) signal, then typing ^C when the CPU goes to 100%, and looking at the stack trace.  (See caller for more details).

For example:

use strict; use warnings; $SIG{INT} = sub { my (@stack, $level); while (1) { my ($pkg, $fn, $ln, $sub) = caller($level++); if (!($pkg or $fn or $ln or $sub)) { for (my $i = 0; $i < @stack; $i++) { print " " x $i, $stack[$i], "\n"; } exit; } unshift @stack, "-> $pkg: $fn (line $ln) sub $sub"; } }; # Your program here ....


s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: Program Hangs
by anbarasans85 (Initiate) on Dec 05, 2010 at 04:14 UTC
    Hi All, Thanks for the reply. I read the comment about minimum sample code to be presented. But I am posting all here. (I am not able to edit). The comments will be useful in understanding the code.
    #!/usr/bin/perl # #Program to calculate end to end delay. # #1. Program reads the trace file, finds for combination of 's' source +event and 'AGT' packet type. #2. For this combination, the program takes the packet id and timestam +p. #3. Within the same file, the program searches for a combination of 'r +' receive event and 'AGT' packet type. #4. For this combination, the program takes the packet id and compares + with previous packet id. If they are same, timestamp is noted. #5. Difference between step 4 timestamp and step 3 timestamp gives the + end to end delay for that packet. #6. Delays are aggregated and average delay is found. # #use strict; use warnings; $SIG{INT} = sub { my (@stack, $level); while(1) { my ($pkg, $fn, $ln, $sub) = caller($level++); if (!($pkg or $fn or $ln or $sub)) { for (my $i = 0; $i < @stack; $i++) { print " " x $i, $stack[$i], "\n"; } exit; } unshift @stack, "-> $pkg: $fn (line $ln) sub $sub"; } }; #Input trace file my($infile) =$ARGV[0]; #Keep track of variables my($enqueue_time) = 0; my($receive_time) = 0; my($packet_id) = 0; my($delay) = 0; my($total_receive_count) = 0; my($sum_of_delay) = 0; my($average_delay) = 0; my($simulation_time) = 0; my($file_position) = 0; my (@x); open(DATA,"<","$infile" ) || die "could't open $infile$!"; while(<DATA>) { @x=split(' '); if(($x[0] eq 's') && ($x[3] eq 'AGT')) { $file_position = tell(DATA); $enqueue_time = $x[1]; $packet_id = $x[5]; while(<DATA>) { ===LINE 58: @x=split(' '); if(($x[0] eq 'r') && ($x[3] eq 'AGT')) { if(($x[5] == $packet_id)) { $receive_time = $x[1]; $total_receive_count++; $delay = $receive_time - $enqueue_time; $sum_of_delay = $sum_of_delay + $delay; #Following is for debug. $delay = $delay * 1000; print("\nDelay:$delay"); last; } } } #Continue to search for next 's' event from where the previous + 's' was found. #So move to the same line where previous 's' event was found. ====LINE 78: seek(DATA,$file_position,SEEK_SET); } #While(<DATA>) takes care of moving to the next line. } $simulation_time = $x[1]; print("\n Simulation Time = $simulation_time seconds"); print("\n Total Receive Count = $total_receive_count"); if($total_receive_count != 0 ) { $average_delay = $sum_of_delay / $total_receive_count; $average_delay = $average_delay * 1000; print("\n Average End to End Delay = $average_delay milliseconds") +; } else { print("\n No packet received."); } print("\n"); print("\n"); close DATA; exit(0);

    About the statements like "very quickly" "for some more time"...:
    1. When I use a trace file with 800 lines, the script successfully completes without any problem.
    2. When I use 80 MB trace file, it hangs. It stops within 12.456 seconds after invoking the script. stops at line 58. main: e2edelay.pl (line 58) sub main::__ANON__
    3. When I use 100MB trace file, it hangs. It stops within 1.982 seconds after invoking the script. Stops at line 58. Same stack message.
    4. When I use 107 MB trace file, it hangs. It stops within 0.4 seconds after invoking the script. Stops at line 58. Same stack message.

    One comment: If the program works for small trace file, why it does not work for larger file?
    Using "use strict" command throws error "Bareword "SEEK_SET" not allowed while "strict subs" in use at e2edelay.pl line 78."

    I have marked line number in the code: LINE <num>
      Hi anbarasans85,

      It's not easy to tell without access to your specific data.

      However, one thing that strikes me as dangerous is:

      while(<DATA>) { #... if(($x[0] eq 's') && ($x[3] eq 'AGT')) { $file_position = tell(DATA); #... while(<DATA>) { #... } seek(DATA,$file_position,SEEK_SET); } }

      Which just has "infinite loop" written all over it.  As soon as you're done reading from <DATA>, you jump back to the marked $file_position which you previously saved.

      Try putting a print statement in the outer loop, and see if that isn't the problem.


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
      Using "use strict" command throws error "Bareword "SEEK_SET" not allowed ...

      SEEK_SET is a constant imported from Fcntl (see seek, first paragraph):
          use Fcntl qw(SEEK_SET);
      or
          use Fcntl qw(:seek);

      Import it and restore use strict;

      Update: So, WHENCE are you seeking if SEEK_SET is not defined in your program? My guess is it's the same as using 0, but that's not tested.