Why can't errno's value be printed?

octopusgrabbus picture octopusgrabbus · Jul 15, 2012 · Viewed 13.8k times · Source

I am looking at the following code in an SO "Low Quality" post to make sure the sample works, and my question is why can't I print errno's value?

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

int main(){
    FILE *fp;
    errno = 0;
    fp=fopen("Not_exist.txt","r");
    if(fp == NULL && errno == ENOENT)
        perror("file not exist");
    return 0;
}

Here is what happens when I try to print the value:

(gdb) p errno
Cannot find thread-local variables on this target
(gdb)

I can print fp's value just fine. As you would expect it's value is 0x00.

I looked at /usr/include/errno.h and a lot of the other include files included as part of errno.h, and I cannot figure out how errno is defined. Any pointers or help would be appreciated. I'm just curious about it; nothing is broken.

Thank you.

Answer

Greg Hewgill picture Greg Hewgill · Jul 15, 2012

The errno variable is kind of an odd duck. Because most runtime libraries these days support threads, there can't be just one errno variable. If there were, then two threads could do things at the same time that both set the errno value, and great confusion would ensue.

Runtime libraries do various tricks to avoid this problem. For example, one might do something like:

#define errno __get_errno()

where references to errno actually call the internal __get_errno() function, which returns the correct error number value for the current thread. The disadvantage of this method is it prevents assignment to errno, such as errno = 0; (which some code might do). Runtime libraries will usually choose a more sophisticated approach.

Some runtime libraries (like the one you're using, I suppose) can declare a special type of "thread-local variable" which can have a different value on each thread. It sounds like your debugger on your system can't display that kind of variable.