[solved] Newlib errno issues
[solved] Newlib errno issues
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.
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.
Re: Newlib errno issues
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.
Re: Newlib errno issues
For example, the errno on a random Linux box I just checked is defined as:
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
Code: Select all
# define errno (*__errno_location ())
EDIT: I see that the wiki page on porting Newlib does an undef and then uses the global errno.
JAL
Re: Newlib errno issues
Of course you can. __errno_location() returns a pointer to the location of errno, which is then dereferenced to yield the expected integer.jal wrote:For example, the errno on a random Linux box I just checked is defined as:So you cannot really assign that a value.Code: Select all
# define errno (*__errno_location ())
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.
Re: Newlib errno issues
Indeed, I don't know what I was thinking... Induced by sleep deprivation, probably...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?
JAL
Re: Newlib errno issues
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.
Re: Newlib errno issues
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.
- Owen
- Member
- Posts: 1700
- Joined: Fri Jun 13, 2008 3:21 pm
- Location: Cambridge, United Kingdom
- Contact:
Re: Newlib errno issues
"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)
-
- Posts: 23
- Joined: Wed Feb 02, 2011 12:30 pm
- Location: Belo Horizonte, Minas Gerais, Brazil
- Contact:
Re: [solved] Newlib errno issues
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.
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/
Undergraduate student of Computer Engineering.
Current OS Project: http://nanvix.blogspot.com/
Re: [solved] Newlib errno issues
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.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.
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 ?
-
- Posts: 23
- Joined: Wed Feb 02, 2011 12:30 pm
- Location: Belo Horizonte, Minas Gerais, Brazil
- Contact:
Re: [solved] Newlib errno issues
Thanks for the quick response gerryg400! I really need this tip. It helped me a lot.
Cheers,
Whitebird
Cheers,
Whitebird
Pedro H. Penna.
Undergraduate student of Computer Engineering.
Current OS Project: http://nanvix.blogspot.com/
Undergraduate student of Computer Engineering.
Current OS Project: http://nanvix.blogspot.com/
Re: [solved] Newlib errno issues
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...gerryg400 wrote:It's best if the kernel never touches it and the variable is managed by your c library.
...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).#define errno (*__errno_location ())
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.