[solved] Newlib errno issues

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
RobertF
Member
Member
Posts: 25
Joined: Tue Oct 18, 2011 12:55 am

[solved] Newlib errno issues

Post by RobertF »

I've been having issues with errno: it refuses to set. Originally when trying to access errno, I would page fault. I discovered that it was because I was not mapping it when I parsed the ELF. Now I can access it just fine, but even using all the minimal implementations of the system calls for newlib appears to not set errno. Another thing I've noticed is that it will work properly if I set errno within my program (which seems obvious that it would), but just not when being set in _read(), _write(), etc.

I'm unsure of what information I'd need to provide here, so I'll update this post as more info is required.
Last edited by RobertF on Tue Oct 25, 2011 5:40 pm, edited 1 time in total.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Newlib errno issues

Post by Solar »

Check out the errno.h header, and find out what the implementation of errno actually is. It might rely on some internal workings, some memory area set up or something like that. Without looking at the source, it's hard to say.
Every good solution is obvious once you've found it.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Newlib errno issues

Post by jal »

For example, the errno on a random Linux box I just checked is defined as:

Code: Select all

#   define errno (*__errno_location ())
So you cannot really assign that a value.

EDIT: I see that the wiki page on porting Newlib does an undef and then uses the global errno.


JAL
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Newlib errno issues

Post by Solar »

jal wrote:For example, the errno on a random Linux box I just checked is defined as:

Code: Select all

#   define errno (*__errno_location ())
So you cannot really assign that a value.
Of course you can. __errno_location() returns a pointer to the location of errno, which is then dereferenced to yield the expected integer.

The point being that __errno_location() is at liberty to return different values, e.g. for different threads. But of course you can assign values to it. Without the ability to errno = 0, the whole mechanism would be rather pointless, wouldn't it?
Every good solution is obvious once you've found it.
jal
Member
Member
Posts: 1385
Joined: Wed Oct 31, 2007 9:09 am

Re: Newlib errno issues

Post by jal »

Solar wrote:But of course you can assign values to it. Without the ability to errno = 0, the whole mechanism would be rather pointless, wouldn't it?
Indeed, I don't know what I was thinking... Induced by sleep deprivation, probably...


JAL
RobertF
Member
Member
Posts: 25
Joined: Tue Oct 18, 2011 12:55 am

Re: Newlib errno issues

Post by RobertF »

Apparently I wasn't mapping data from the .data section header correctly—now errno reads properly, but only when it isn't redefined as an extern int.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: Newlib errno issues

Post by Solar »

Might be that some part of the newlib code messes with the internals of __errno_location() directly and doesn't like having errno redefined. (Might be worth a find / grep. ;-) )
Every good solution is obvious once you've found it.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Newlib errno issues

Post by Owen »

"extern int errno" is undefined behavior per C88/C99/C1X. That said, it is sometimes used in old (pre-threads) Unix software, so if you intend to be Unix compatible may prove useful to implement (make the "errno" symbol refer to the errno value for the "main" thread)
Whitebird
Posts: 23
Joined: Wed Feb 02, 2011 12:30 pm
Location: Belo Horizonte, Minas Gerais, Brazil
Contact:

Re: [solved] Newlib errno issues

Post by Whitebird »

Hi,

I decided to take advantage of this old post to ask a similar question that might be stupid but I'm stuck on it.

I did't get how to implement the errno variable. I mean: do I need to have a file "errno.c", which is linked with the kernel?
How do I handle with errno references declared in "user programs"? Whenever an executable is loaded, I must resolve this "external references" looking for errno references in the symbols table and then linking them with the kernel variable?

Thanks in advance.
Pedro H. Penna.

Undergraduate student of Computer Engineering.

Current OS Project: http://nanvix.blogspot.com/
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: [solved] Newlib errno issues

Post by gerryg400 »

Whitebird wrote:Hi,

I decided to take advantage of this old post to ask a similar question that might be stupid but I'm stuck on it.

I did't get how to implement the errno variable. I mean: do I need to have a file "errno.c", which is linked with the kernel?
How do I handle with errno references declared in "user programs"? Whenever an executable is loaded, I must resolve this "external references" looking for errno references in the symbols table and then linking them with the kernel variable?

Thanks in advance.
Firstly, errno is a user-space variable. It should be linked into the c library. It's best if the kernel never touches it and the variable is managed by your c library. There are a few ways to do this. I do it like this. If the kernel returns a negative number from a system call then that is an error and the absolute value of the return value is the error number.

Code: Select all

ssize_t read(int fildes, void *buf, size_t nbyte) {

    ssize_t     ret;

    if ((ret = anvil_read(fildes, buf, nbyte, -1)) < 0) {
        errno = -ret;
        return -1;
    }

    return ret;
}
If a trainstation is where trains stop, what is a workstation ?
Whitebird
Posts: 23
Joined: Wed Feb 02, 2011 12:30 pm
Location: Belo Horizonte, Minas Gerais, Brazil
Contact:

Re: [solved] Newlib errno issues

Post by Whitebird »

Thanks for the quick response gerryg400! I really need this tip. It helped me a lot.

Cheers,


Whitebird
Pedro H. Penna.

Undergraduate student of Computer Engineering.

Current OS Project: http://nanvix.blogspot.com/
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: [solved] Newlib errno issues

Post by Solar »

gerryg400 wrote:It's best if the kernel never touches it and the variable is managed by your c library.
One point I came to realize while working on the PDCLib, more exactly, Plaugher's excellent book on the subject. The reason for this indirection...
#define errno (*__errno_location ())
...is that this allows the library to defer setting errno to when (and if) it is actually read (i.e., the function __errno_location() is actually being called).

It is not obvious why this would be necessary for stuff like I/O, where errno is set in direct response to something the kernel does, but (according to Plaugher, haven't tested it myself yet) it makes a world of difference for the math functions. Consider your C library using FPU functionality to implement those. Now consider what would be necessary if errno were simply defined to be an integer somewhere in memory. You would have to read out the FPU status flag after every math function. There goes your performance...

With the above mechanism, you need to read the FPU status flag only if errno were actually accessed.
Every good solution is obvious once you've found it.
Post Reply