Home>
Program overview

In c language, I am writing a program to check if the server is running based on the data read from the file.

File to read
20201019133124,10.20.30.1/16,2
20201019133125,10.20.30.2/16,1
20201019133134,192.168.1.1/24,10
20201019133135,192.168.1.2/24, 5
20201019133224,10.20.30.1/16,522
20201019133225,10.20.30.2/16,1
20201019133234,192.168.1.1/24,8
20201019133235,192.168.1.2/24,15
20201019133324, 10.20.30.1/16,-
20201019133325,10.20.30.2/16,2
20201019133334, 10.20.30.1/16,-
20201019134040,10.20.30.1/16,5
20201019134440, 10.20.30.1/16,-
20201019134450, 10.20.30.1/16,5
20201019134460, 192.168.1.1/24,-
20201019135050,192.168.1.2/24,15

From the left, the order is,, and.
If-is returned in the response result, it is considered as a server failure.

Server 10.20.30.1/16 is out of order
The failure period is 1 second
Server 10.20.30.1/16 is out of order
The failure period is 7 minutes and 6 seconds
Server 10.20.30.1/16 is out of order
The failure period is 10 seconds
Server 192.168.1.1/24 is out of order
The failure period is 5 minutes and 90 seconds
zsh: abort ./a.out
Corresponding source code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 50
struct LOG {
  long time;
  char server_name [N];
  char result [N];
};
void printTime (long kikan) {
  char kikan2 [14];
  sprintf (kikan2, "% ld", kikan);
  int len ​​= strlen (kikan2);
  long sec, min, hour, day, month, year;
  year = kikan/100000000000;
  month = (kikan/100000)% 100;
  day = (kikan/10000)% 100;
  hour = (kikan/100)% 100;
  min = kikan/100;
  sec = kikan% 100;

  if (len<= 2) {
    printf ("Failure period is% ld seconds \ n", sec);
  } else if (len<= 4) {
    printf ("Failure period is% ld minutes% ld seconds \ n", min, sec);
  } else if (len<= 6) {
    printf ("Failure period is% ld hours% ld minutes% ld seconds \ n", hour, min, sec);
  } else if (len<= 8) {
    printf ("Failure period is% ld day% ld hour% ld minute% ld second \ n", day, hour, min, sec);
  } else if (len<= 10) {
    printf ("Failure period is% ld month% ld day% ld hour% ld minute% ld second \ n", month, day, hour, min, sec);
  } else if (len<= 14) {
    printf ("Failure period is% ld year% ld month% ld day% ld hour% ld minute% ld second \ n", year, month, day, hour, min, sec);
  }
}

int main () {
  FILE * fp;
  struct LOG log [10];
  char s [N] [N], * cp, handan_name [N];

  const char * sikiri = ",";
  long handan_time = 0, kikan;
  int i = 0, j = 0, len = 0, ct = 0;// Judged only once per error by ct

  fp = fopen ("server.txt", "r");
  while (fgets (s [i], N, fp)! = NULL) {
    cp = strtok (s [i], sikiri);
    log [i] .time = atol (cp);// Insert time here, convert from string to number
    int c = 0;
    while (cp! = NULL) {
      cp = strtok (NULL, sikiri);
      if (cp! = NULL&&c == 0) {
    strcpy (log [i] .server_name, cp);// Insert the name of the server here
    c ++;

    if (strcmp (&handan_name [len-1], "1")&&
       strncmp (handan_name, log [i] .server_name, 8) == 0&&ct == 1) {// if (if it is out of order) determine if the server name is on here
      kikan = log [i] .time-handan_time;
      printTime (kikan);
      ct-;
    } else if (strcmp (&handan_name [len-1], "2")&&
         strncmp (handan_name, log [i] .server_name, 9) == 0&&ct == 1) {
      kikan = log [i] .time-handan_time;
      printTime (kikan);
      ct-;
    }
      }
      if (cp! = NULL&&c == 1) {
    strcpy (log [i] .result, cp);// Insert result here
    if (strncmp (log [i] .result, "-", 1) == 0&&ct == 0) {
      printf ("Server% s is out of order \ n", log [i] .server_name);// Determine if the server is out of order
      len = strlen (log [i] .server_name);
      handan_time = log [i] .time;
      strcpy (handan_name, log [i] .server_name);
      ct ++;
    }
      }
    }
    i ++;
  }

  fclose (fp);
  return 0;
}
What I tried

When I investigated it myself, it was written that the error zsh: abort ./a.out was an error related to memory release, but all the examples assume that memory is allocated by malloc, and char I tried to allocate memory for * cp with malloc and free it, but nothing changed.

  • Answer # 1

    In this case, try using Undefined Behavior Sanitiser.
    https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

    The source code of the presented program (since it needs to be compiled as C ++)main.cpp)

    clang ++ main.cpp -Wall -Wextra -pedantic -std = c ++ 17 -g -fsanitize = undefined

    If you compile and run it like

    $./a.out
    main.cpp: 68: 16: runtime error: index -1 out of bounds for type'char [50]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 68:16 in
    main.cpp: 73: 22: runtime error: index -1 out of bounds for type'char [50]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 73:22 in
    Server 10.20.30.1/16 is out of order
    The failure period is 1 second
    main.cpp: 59: 5: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 59: 5 in
    main.cpp: 64: 12: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 64: 12 in
    main.cpp: 69: 28: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 69:28 in
    main.cpp: 74:30: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 74:30 in
    main.cpp: 82: 12: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 82:12 in
    main.cpp: 83: 16: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 83: 16 in
    main.cpp: 84: 54: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 84:54 in
    Server 10.20.30.1/16 is out of order
    main.cpp: 85: 18: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 85:18 in
    main.cpp: 86: 21: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 86:21 in
    main.cpp: 87: 26: runtime error: index 10 out of bounds for type'struct LOG [10]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 87:26 in
    UndefinedBehaviorSanitizer: DEADLYSIGNAL
    == 9562 == ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address (pc 0x7ff102159bab bp 0x7ffd51fcdd26 sp 0x7ffd51fcd790 T9562)
    == 9562 == The signal is caused by a READ memory access.
    == 9562 == Hint: this fault was caused by a dereference of a high value address (see register values ​​below). Dissassemble the provided pc to learn which register was used.
    UndefinedBehaviorSanitizer: DEADLYSIGNAL
    UndefinedBehaviorSanitizer: nested bug in the same thread, aborting.

    You will get the result like this. In other words, there is a general problem with accessing the array.

    I rewrote it a little and tried to prepare the debug log

    #include<stdio.h>#include<stdlib.h>#include<string.h>#define N 50
    struct LOG {
      long time;
      char server_name [N];
      char result [N];
    };
    void printTime (long kikan) {
      char kikan2 [14];
      sprintf (kikan2, "% ld", kikan);
      int len ​​= strlen (kikan2);long sec, min, hour, day, month, year;
      year = kikan/10000000000;
      month = (kikan/1000000)% 100;
      day = (kikan/10000)% 100;
      hour = (kikan/100)% 100;
      min = kikan/100;
      sec = kikan% 100;
      if (len<= 2) {
        printf ("Failure period is% ld seconds \ n", sec);
      } else if (len<= 4) {
        printf ("Failure period is% ld minutes% ld seconds \ n", min, sec);
      } else if (len<= 6) {
        printf ("Failure period is% ld hours% ld minutes% ld seconds \ n", hour, min, sec);
      } else if (len<= 8) {
        printf ("Failure period is% ld day% ld hour% ld minute% ld second \ n", day, hour, min, sec);
      } else if (len<= 10) {
        printf ("Failure period is% ld month% ld day% ld hour% ld minute% ld second \ n", month, day, hour, min, sec);
      } else if (len<= 14) {
        printf ("Failure period is% ld year% ld month% ld day% ld hour% ld minute% ld second \ n", year, month, day, hour, min, sec);
      }
    }
    int main () {
      FILE * fp;
      struct LOG log [30];
      char s [N] [N],
     * cp, handan_name [N];
      const char * sikiri = ",";
      long handan_time = 0, kikan;
      int i = 0, len = 0, ct = 0;// Determined by ct only once per error
      fp = fopen ("server.txt", "r");
      while (fgets (s [i],],
     N, fp)! = NULL) {
        printf ("Debug (line% d): i =% d \ n", __LINE__, i);
        cp = strtok (s [i],
     sikiri);
        log [i] .time = atol (cp);// Insert time here, convert from string to number
        int c = 0;
        while (NULL! = (cp = strtok (NULL, sikiri))) {
          if (c == 0) {
            strcpy (log [i] .server_name, cp);// Insert the name of the server here
            c ++;
            if (strcmp (&handan_name [len -1],
     "1")&&strncmp (handan_name, log [i] .server_name, 8) == 0&&
                ct == 1) {// if (if it's broken) here to determine if the server name is on
              kikan = log [i] .time --handan_time;
              printTime (kikan);
              ct-;
            } else if (strcmp (&handan_name [len -1],
     "2")&&strncmp (handan_name, log [i] .server_name, 9) == 0&&ct == 1) {kikan = log [i] .time --handan_time;
              printTime (kikan);
              ct-;
            }
          }
          if (cp! = NULL&&c == 1) {
            strcpy (log [i] .result, cp);// Insert the result here
            if (strncmp (log [i] .result, "-", 1) == 0&&ct == 0) {
              printf ("Server% s is out of order \ n", log [i] .server_name);// Determine if the server is out of order
              len = strlen (log [i] .server_name);
              handan_time = log [i] .time;
              strcpy (handan_name, log [i] .server_name);
              ct ++;
            }
          }
        }
        i ++;
      }
      fclose (fp);
      return 0;
    }

    If you do the same

    Debug (line 53): i = 0
    main.cpp: 62: 21: runtime error: index -1 out of bounds for type'char [50]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 62:21 in
    main.cpp: 67: 28: runtime error: index -1 out of bounds for type'char [50]'
    MEMS: UndefinedBehaviorSanitizer: undefined-behavior main.cpp: 67: 28 in
    Debug (line 53): i = 1
    Debug (line 53): i = 2
    Debug (line 53): i = 3
    Debug (line 53): i = 4
    Debug (line 53): i = 5
    Debug (line 53): i = 6
    Debug (line 53): i = 7
    Debug (line 53): i = 8
    Server 10.20.30.1/16 is out of order
    Debug (line 53): i = 9
    The failure period is 1 second
    Debug (line 53): i = 10
    Server 10.20.30.1/16 is out of order
    Debug (line 53): i = 11
    The failure period is 7 minutes and 6 seconds
    Debug (line 53): i = 12
    Server 10.20.30.1/16 is out of order
    Debug (line 53): i = 13
    The failure period is 10 seconds
    Debug (line 53): i = 14
    Server 192.168.1.1/24 is out of order
    Debug (line 53): i = 15
    The failure period is 5 minutes and 90 seconds
    Debug (line 53): i = 16

    Variable initialized on line 56cFocusing oncIs 0 only when entering the loop for the first time. At this timelenIs definitely0is. Also involvedlen -1Because it is accessed like, it is an out-of-array reference. This is probably because the logic is wrong.