When do Linux system calls trigger a segfault vs returning EFAULT?












0















I'm trying to understand when clock_gettime() can lead to errors. The man page lists the following two possibilities:




  1. EFAULT tp points outside the accessible address space.

  2. EINVAL The clk_id specified is not supported on this system.


It's easy to trigger an EINVAL error but I'm not able to get clock_gettime() to set errno to EFAULT. Instead, the kernel sends a SIGSEGV signal to terminate the program. For instance, in the following code:



#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
struct timespec tp;
double time;

if (clock_gettime(CLOCK_MONOTONIC, &tp + 4096) == -1) {
if (errno == EINVAL) {
perror("EINVAL");
return EXIT_FAILURE;
} else if (errno == EFAULT) {
perror("EFAULT");
return EXIT_FAILURE;
} else {
perror("something else");
return EXIT_FAILURE;
}
}

time = tp.tv_sec + 1e-9 * tp.tv_nsec;
printf("%fn", time);
}


How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter? If the kernel always sends the signal, is it actually necessary to check whether errno equals EFAULT?



I'm running Linux kernel 4.15 and I compiled the program with (using clang v6.0):
clang -g -O0 -Wall -Wextra -Wshadow -Wstrict-aliasing -ansi -pedantic -Werror -std=gnu11 file.c -o file










share|improve this question

























  • I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

    – immibis
    Nov 19 '18 at 23:20
















0















I'm trying to understand when clock_gettime() can lead to errors. The man page lists the following two possibilities:




  1. EFAULT tp points outside the accessible address space.

  2. EINVAL The clk_id specified is not supported on this system.


It's easy to trigger an EINVAL error but I'm not able to get clock_gettime() to set errno to EFAULT. Instead, the kernel sends a SIGSEGV signal to terminate the program. For instance, in the following code:



#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
struct timespec tp;
double time;

if (clock_gettime(CLOCK_MONOTONIC, &tp + 4096) == -1) {
if (errno == EINVAL) {
perror("EINVAL");
return EXIT_FAILURE;
} else if (errno == EFAULT) {
perror("EFAULT");
return EXIT_FAILURE;
} else {
perror("something else");
return EXIT_FAILURE;
}
}

time = tp.tv_sec + 1e-9 * tp.tv_nsec;
printf("%fn", time);
}


How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter? If the kernel always sends the signal, is it actually necessary to check whether errno equals EFAULT?



I'm running Linux kernel 4.15 and I compiled the program with (using clang v6.0):
clang -g -O0 -Wall -Wextra -Wshadow -Wstrict-aliasing -ansi -pedantic -Werror -std=gnu11 file.c -o file










share|improve this question

























  • I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

    – immibis
    Nov 19 '18 at 23:20














0












0








0








I'm trying to understand when clock_gettime() can lead to errors. The man page lists the following two possibilities:




  1. EFAULT tp points outside the accessible address space.

  2. EINVAL The clk_id specified is not supported on this system.


It's easy to trigger an EINVAL error but I'm not able to get clock_gettime() to set errno to EFAULT. Instead, the kernel sends a SIGSEGV signal to terminate the program. For instance, in the following code:



#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
struct timespec tp;
double time;

if (clock_gettime(CLOCK_MONOTONIC, &tp + 4096) == -1) {
if (errno == EINVAL) {
perror("EINVAL");
return EXIT_FAILURE;
} else if (errno == EFAULT) {
perror("EFAULT");
return EXIT_FAILURE;
} else {
perror("something else");
return EXIT_FAILURE;
}
}

time = tp.tv_sec + 1e-9 * tp.tv_nsec;
printf("%fn", time);
}


How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter? If the kernel always sends the signal, is it actually necessary to check whether errno equals EFAULT?



I'm running Linux kernel 4.15 and I compiled the program with (using clang v6.0):
clang -g -O0 -Wall -Wextra -Wshadow -Wstrict-aliasing -ansi -pedantic -Werror -std=gnu11 file.c -o file










share|improve this question
















I'm trying to understand when clock_gettime() can lead to errors. The man page lists the following two possibilities:




  1. EFAULT tp points outside the accessible address space.

  2. EINVAL The clk_id specified is not supported on this system.


It's easy to trigger an EINVAL error but I'm not able to get clock_gettime() to set errno to EFAULT. Instead, the kernel sends a SIGSEGV signal to terminate the program. For instance, in the following code:



#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

int main()
{
struct timespec tp;
double time;

if (clock_gettime(CLOCK_MONOTONIC, &tp + 4096) == -1) {
if (errno == EINVAL) {
perror("EINVAL");
return EXIT_FAILURE;
} else if (errno == EFAULT) {
perror("EFAULT");
return EXIT_FAILURE;
} else {
perror("something else");
return EXIT_FAILURE;
}
}

time = tp.tv_sec + 1e-9 * tp.tv_nsec;
printf("%fn", time);
}


How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter? If the kernel always sends the signal, is it actually necessary to check whether errno equals EFAULT?



I'm running Linux kernel 4.15 and I compiled the program with (using clang v6.0):
clang -g -O0 -Wall -Wextra -Wshadow -Wstrict-aliasing -ansi -pedantic -Werror -std=gnu11 file.c -o file







c linux error-handling






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 23:24







MattHusz

















asked Nov 19 '18 at 23:18









MattHuszMattHusz

7516




7516













  • I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

    – immibis
    Nov 19 '18 at 23:20



















  • I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

    – immibis
    Nov 19 '18 at 23:20

















I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

– immibis
Nov 19 '18 at 23:20





I don't believe that a system call can ever segfault. However, glibc can segfault, and a lot of functions that you think are system calls are actually glibc functions.

– immibis
Nov 19 '18 at 23:20












2 Answers
2






active

oldest

votes


















1














clock_gettime is probably not executing as a syscall, but rather in userspace as part of the vdso. If you actually perform a syscall by using the syscall function with SYS_clock_gettime as its argument, I would expect you to see EFAULT.



With that said, EFAULT is not ever something you should expect to be able to rely on. As soon as you pass an invalid pointer to a function that requires a valid pointer as part of its interface contract, you have undefined behavior, and a segfault or an error is only one possible manifestation among many. From this perspective it's something of a mistake that EFAULT is even documented.






share|improve this answer































    0















    I'm trying to understand when clock_gettime() can lead to errors.




    Ok.




    How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter?




    It's easy. There are some checks in case they are true the function sets errno. In case you access a protected memory region the kernel sends SIGSEGV to your process.



    If you inspect the __clock_gettime from glibc function you see that:



    switch (clock_id)
    {
    #ifdef SYSDEP_GETTIME
    SYSDEP_GETTIME;
    #endif

    #ifndef HANDLED_REALTIME
    case CLOCK_REALTIME:
    ...
    break;
    #endif

    default:
    #if HP_TIMING_AVAIL
    if ((clock_id ...) == CLOCK_THREAD_CPUTIME_ID)
    ...
    else
    #endif
    __set_errno (EINVAL);
    break;


    The glibc wrapper set's EINVAL in case of some strange clock_id value.



    Dereferencing a pointer value outside any valid memory reagion in undefined bahaviour and spawns nasal demons. On Linux a SIGSEGV is a signal sent to a process which tries to write to a protected memory region.



    The following code spawns demons and should raise SIGSEGV:



    struct timespec tp;
    *(&tp + 4096) = (struct timespec){0};


    so does the following code:



    struct timespec tp;
    clock_gettime(CLOCK_MONOTONIC, &tp + 4096)



    If the kernel always sends the signal,




    Not really. If it so just happens that sizeof(struct timespec) bytes starting from &tp + 4096 will not be inside protected memory region, the kernel will not send any signal, cause it would think, you write inside you own memory.




    is it actually necessary to check whether errno equals EFAULT?




    It's not necessary to check for any errors. I think you mix interpreting errors with checking for them. If you machine follows the specification you mentioned, if clock_gettime returns EFAULT you can write your program so it assumes that the underlying implementation on your machine of clock_gettime follows the linux manual page of clock_gettime. However, as you discovered, it does not, instead undefined bahaviour happens and the kernel raises SIGSEGV. Which only means that the underlying implementation of the clock_gettime function does not follow the manual. The POSIX does not specify the EFAULT errno code. However I believe there may exists implementations which may return EFAULT errno or any other errno codes. However, what do you want your program to do when receiving EFAULT error? How to recover from such error? If these question bear any significance to you, then it may be reasonable to write an EFAULT handler for the clock_gettime function.



    Please note, you are using linux. Linux, kernel and glibc, mostly are licensed under the GNU General License or GNU Lesser General License, which has the following in it:




    BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.




    The question bears down to trust: do you believe your system's clock_gettime() to follow the linux manual implementation? I don't. If your system would be POSIX certificate, you could place some more trust in the functions that they will work as the manual says. No one guarantees you that, it is just a good will of many hardworking people that it works.






    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384022%2fwhen-do-linux-system-calls-trigger-a-segfault-vs-returning-efault%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      clock_gettime is probably not executing as a syscall, but rather in userspace as part of the vdso. If you actually perform a syscall by using the syscall function with SYS_clock_gettime as its argument, I would expect you to see EFAULT.



      With that said, EFAULT is not ever something you should expect to be able to rely on. As soon as you pass an invalid pointer to a function that requires a valid pointer as part of its interface contract, you have undefined behavior, and a segfault or an error is only one possible manifestation among many. From this perspective it's something of a mistake that EFAULT is even documented.






      share|improve this answer




























        1














        clock_gettime is probably not executing as a syscall, but rather in userspace as part of the vdso. If you actually perform a syscall by using the syscall function with SYS_clock_gettime as its argument, I would expect you to see EFAULT.



        With that said, EFAULT is not ever something you should expect to be able to rely on. As soon as you pass an invalid pointer to a function that requires a valid pointer as part of its interface contract, you have undefined behavior, and a segfault or an error is only one possible manifestation among many. From this perspective it's something of a mistake that EFAULT is even documented.






        share|improve this answer


























          1












          1








          1







          clock_gettime is probably not executing as a syscall, but rather in userspace as part of the vdso. If you actually perform a syscall by using the syscall function with SYS_clock_gettime as its argument, I would expect you to see EFAULT.



          With that said, EFAULT is not ever something you should expect to be able to rely on. As soon as you pass an invalid pointer to a function that requires a valid pointer as part of its interface contract, you have undefined behavior, and a segfault or an error is only one possible manifestation among many. From this perspective it's something of a mistake that EFAULT is even documented.






          share|improve this answer













          clock_gettime is probably not executing as a syscall, but rather in userspace as part of the vdso. If you actually perform a syscall by using the syscall function with SYS_clock_gettime as its argument, I would expect you to see EFAULT.



          With that said, EFAULT is not ever something you should expect to be able to rely on. As soon as you pass an invalid pointer to a function that requires a valid pointer as part of its interface contract, you have undefined behavior, and a segfault or an error is only one possible manifestation among many. From this perspective it's something of a mistake that EFAULT is even documented.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 19 '18 at 23:25









          R..R..

          156k26260563




          156k26260563

























              0















              I'm trying to understand when clock_gettime() can lead to errors.




              Ok.




              How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter?




              It's easy. There are some checks in case they are true the function sets errno. In case you access a protected memory region the kernel sends SIGSEGV to your process.



              If you inspect the __clock_gettime from glibc function you see that:



              switch (clock_id)
              {
              #ifdef SYSDEP_GETTIME
              SYSDEP_GETTIME;
              #endif

              #ifndef HANDLED_REALTIME
              case CLOCK_REALTIME:
              ...
              break;
              #endif

              default:
              #if HP_TIMING_AVAIL
              if ((clock_id ...) == CLOCK_THREAD_CPUTIME_ID)
              ...
              else
              #endif
              __set_errno (EINVAL);
              break;


              The glibc wrapper set's EINVAL in case of some strange clock_id value.



              Dereferencing a pointer value outside any valid memory reagion in undefined bahaviour and spawns nasal demons. On Linux a SIGSEGV is a signal sent to a process which tries to write to a protected memory region.



              The following code spawns demons and should raise SIGSEGV:



              struct timespec tp;
              *(&tp + 4096) = (struct timespec){0};


              so does the following code:



              struct timespec tp;
              clock_gettime(CLOCK_MONOTONIC, &tp + 4096)



              If the kernel always sends the signal,




              Not really. If it so just happens that sizeof(struct timespec) bytes starting from &tp + 4096 will not be inside protected memory region, the kernel will not send any signal, cause it would think, you write inside you own memory.




              is it actually necessary to check whether errno equals EFAULT?




              It's not necessary to check for any errors. I think you mix interpreting errors with checking for them. If you machine follows the specification you mentioned, if clock_gettime returns EFAULT you can write your program so it assumes that the underlying implementation on your machine of clock_gettime follows the linux manual page of clock_gettime. However, as you discovered, it does not, instead undefined bahaviour happens and the kernel raises SIGSEGV. Which only means that the underlying implementation of the clock_gettime function does not follow the manual. The POSIX does not specify the EFAULT errno code. However I believe there may exists implementations which may return EFAULT errno or any other errno codes. However, what do you want your program to do when receiving EFAULT error? How to recover from such error? If these question bear any significance to you, then it may be reasonable to write an EFAULT handler for the clock_gettime function.



              Please note, you are using linux. Linux, kernel and glibc, mostly are licensed under the GNU General License or GNU Lesser General License, which has the following in it:




              BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.




              The question bears down to trust: do you believe your system's clock_gettime() to follow the linux manual implementation? I don't. If your system would be POSIX certificate, you could place some more trust in the functions that they will work as the manual says. No one guarantees you that, it is just a good will of many hardworking people that it works.






              share|improve this answer




























                0















                I'm trying to understand when clock_gettime() can lead to errors.




                Ok.




                How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter?




                It's easy. There are some checks in case they are true the function sets errno. In case you access a protected memory region the kernel sends SIGSEGV to your process.



                If you inspect the __clock_gettime from glibc function you see that:



                switch (clock_id)
                {
                #ifdef SYSDEP_GETTIME
                SYSDEP_GETTIME;
                #endif

                #ifndef HANDLED_REALTIME
                case CLOCK_REALTIME:
                ...
                break;
                #endif

                default:
                #if HP_TIMING_AVAIL
                if ((clock_id ...) == CLOCK_THREAD_CPUTIME_ID)
                ...
                else
                #endif
                __set_errno (EINVAL);
                break;


                The glibc wrapper set's EINVAL in case of some strange clock_id value.



                Dereferencing a pointer value outside any valid memory reagion in undefined bahaviour and spawns nasal demons. On Linux a SIGSEGV is a signal sent to a process which tries to write to a protected memory region.



                The following code spawns demons and should raise SIGSEGV:



                struct timespec tp;
                *(&tp + 4096) = (struct timespec){0};


                so does the following code:



                struct timespec tp;
                clock_gettime(CLOCK_MONOTONIC, &tp + 4096)



                If the kernel always sends the signal,




                Not really. If it so just happens that sizeof(struct timespec) bytes starting from &tp + 4096 will not be inside protected memory region, the kernel will not send any signal, cause it would think, you write inside you own memory.




                is it actually necessary to check whether errno equals EFAULT?




                It's not necessary to check for any errors. I think you mix interpreting errors with checking for them. If you machine follows the specification you mentioned, if clock_gettime returns EFAULT you can write your program so it assumes that the underlying implementation on your machine of clock_gettime follows the linux manual page of clock_gettime. However, as you discovered, it does not, instead undefined bahaviour happens and the kernel raises SIGSEGV. Which only means that the underlying implementation of the clock_gettime function does not follow the manual. The POSIX does not specify the EFAULT errno code. However I believe there may exists implementations which may return EFAULT errno or any other errno codes. However, what do you want your program to do when receiving EFAULT error? How to recover from such error? If these question bear any significance to you, then it may be reasonable to write an EFAULT handler for the clock_gettime function.



                Please note, you are using linux. Linux, kernel and glibc, mostly are licensed under the GNU General License or GNU Lesser General License, which has the following in it:




                BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.




                The question bears down to trust: do you believe your system's clock_gettime() to follow the linux manual implementation? I don't. If your system would be POSIX certificate, you could place some more trust in the functions that they will work as the manual says. No one guarantees you that, it is just a good will of many hardworking people that it works.






                share|improve this answer


























                  0












                  0








                  0








                  I'm trying to understand when clock_gettime() can lead to errors.




                  Ok.




                  How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter?




                  It's easy. There are some checks in case they are true the function sets errno. In case you access a protected memory region the kernel sends SIGSEGV to your process.



                  If you inspect the __clock_gettime from glibc function you see that:



                  switch (clock_id)
                  {
                  #ifdef SYSDEP_GETTIME
                  SYSDEP_GETTIME;
                  #endif

                  #ifndef HANDLED_REALTIME
                  case CLOCK_REALTIME:
                  ...
                  break;
                  #endif

                  default:
                  #if HP_TIMING_AVAIL
                  if ((clock_id ...) == CLOCK_THREAD_CPUTIME_ID)
                  ...
                  else
                  #endif
                  __set_errno (EINVAL);
                  break;


                  The glibc wrapper set's EINVAL in case of some strange clock_id value.



                  Dereferencing a pointer value outside any valid memory reagion in undefined bahaviour and spawns nasal demons. On Linux a SIGSEGV is a signal sent to a process which tries to write to a protected memory region.



                  The following code spawns demons and should raise SIGSEGV:



                  struct timespec tp;
                  *(&tp + 4096) = (struct timespec){0};


                  so does the following code:



                  struct timespec tp;
                  clock_gettime(CLOCK_MONOTONIC, &tp + 4096)



                  If the kernel always sends the signal,




                  Not really. If it so just happens that sizeof(struct timespec) bytes starting from &tp + 4096 will not be inside protected memory region, the kernel will not send any signal, cause it would think, you write inside you own memory.




                  is it actually necessary to check whether errno equals EFAULT?




                  It's not necessary to check for any errors. I think you mix interpreting errors with checking for them. If you machine follows the specification you mentioned, if clock_gettime returns EFAULT you can write your program so it assumes that the underlying implementation on your machine of clock_gettime follows the linux manual page of clock_gettime. However, as you discovered, it does not, instead undefined bahaviour happens and the kernel raises SIGSEGV. Which only means that the underlying implementation of the clock_gettime function does not follow the manual. The POSIX does not specify the EFAULT errno code. However I believe there may exists implementations which may return EFAULT errno or any other errno codes. However, what do you want your program to do when receiving EFAULT error? How to recover from such error? If these question bear any significance to you, then it may be reasonable to write an EFAULT handler for the clock_gettime function.



                  Please note, you are using linux. Linux, kernel and glibc, mostly are licensed under the GNU General License or GNU Lesser General License, which has the following in it:




                  BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.




                  The question bears down to trust: do you believe your system's clock_gettime() to follow the linux manual implementation? I don't. If your system would be POSIX certificate, you could place some more trust in the functions that they will work as the manual says. No one guarantees you that, it is just a good will of many hardworking people that it works.






                  share|improve this answer














                  I'm trying to understand when clock_gettime() can lead to errors.




                  Ok.




                  How does the Linux kernel choose between triggering a segmentation fault and having the system call return -EINVAL? When will it choose to do the latter?




                  It's easy. There are some checks in case they are true the function sets errno. In case you access a protected memory region the kernel sends SIGSEGV to your process.



                  If you inspect the __clock_gettime from glibc function you see that:



                  switch (clock_id)
                  {
                  #ifdef SYSDEP_GETTIME
                  SYSDEP_GETTIME;
                  #endif

                  #ifndef HANDLED_REALTIME
                  case CLOCK_REALTIME:
                  ...
                  break;
                  #endif

                  default:
                  #if HP_TIMING_AVAIL
                  if ((clock_id ...) == CLOCK_THREAD_CPUTIME_ID)
                  ...
                  else
                  #endif
                  __set_errno (EINVAL);
                  break;


                  The glibc wrapper set's EINVAL in case of some strange clock_id value.



                  Dereferencing a pointer value outside any valid memory reagion in undefined bahaviour and spawns nasal demons. On Linux a SIGSEGV is a signal sent to a process which tries to write to a protected memory region.



                  The following code spawns demons and should raise SIGSEGV:



                  struct timespec tp;
                  *(&tp + 4096) = (struct timespec){0};


                  so does the following code:



                  struct timespec tp;
                  clock_gettime(CLOCK_MONOTONIC, &tp + 4096)



                  If the kernel always sends the signal,




                  Not really. If it so just happens that sizeof(struct timespec) bytes starting from &tp + 4096 will not be inside protected memory region, the kernel will not send any signal, cause it would think, you write inside you own memory.




                  is it actually necessary to check whether errno equals EFAULT?




                  It's not necessary to check for any errors. I think you mix interpreting errors with checking for them. If you machine follows the specification you mentioned, if clock_gettime returns EFAULT you can write your program so it assumes that the underlying implementation on your machine of clock_gettime follows the linux manual page of clock_gettime. However, as you discovered, it does not, instead undefined bahaviour happens and the kernel raises SIGSEGV. Which only means that the underlying implementation of the clock_gettime function does not follow the manual. The POSIX does not specify the EFAULT errno code. However I believe there may exists implementations which may return EFAULT errno or any other errno codes. However, what do you want your program to do when receiving EFAULT error? How to recover from such error? If these question bear any significance to you, then it may be reasonable to write an EFAULT handler for the clock_gettime function.



                  Please note, you are using linux. Linux, kernel and glibc, mostly are licensed under the GNU General License or GNU Lesser General License, which has the following in it:




                  BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.




                  The question bears down to trust: do you believe your system's clock_gettime() to follow the linux manual implementation? I don't. If your system would be POSIX certificate, you could place some more trust in the functions that they will work as the manual says. No one guarantees you that, it is just a good will of many hardworking people that it works.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 19 '18 at 23:56









                  Kamil CukKamil Cuk

                  10.4k1527




                  10.4k1527






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384022%2fwhen-do-linux-system-calls-trigger-a-segfault-vs-returning-efault%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      How to change which sound is reproduced for terminal bell?

                      Title Spacing in Bjornstrup Chapter, Removing Chapter Number From Contents

                      Can I use Tabulator js library in my java Spring + Thymeleaf project?