Testing `errno` after calling `strtol` returns "No such process" - ios

Even though the string conversion succeeds, testing errnoreturns a value indicating an error:
#include <stdlib.h>
#include <sys/errno.h>
const char* numberString = "7";
char* endPtr;
errno = 0;
long number = strtol(numberString, &endPtr, 10);
NSLog(#"%ld", number);
if (errno) {
perror("string to integer conversion failed");
}
The output is (on the Simulator, iOS 7)
$ 2014-05-22 09:27:32.954 Test[2144:60b] 7
$ string to integer conversion failed: No such process
The behavior is similar on the device.
The man page for strtol says in a comment:
RETURN VALUES
The strtol(), strtoll(), strtoimax(), and strtoq() functions return the result of the conversion,
unless the value would underflow or overflow. If no conversion could be performed, 0 is returned and
the global variable errno is set to EINVAL (the last feature is not portable across all platforms). If
an overflow or underflow occurs, errno is set to ERANGE and the function return value is clamped
according to the following table.
It's quite unclear what this exactly means for iOS. Any insights here?
Edit:
It turned out that the function call NSLog did set errno. So, #Mat in his answer and comments was spot on, saying that "all bets are off when testing errno AFTER calling an unrelated function (here NSLog).

If no conversion could be performed, 0 is returned
You're not in that case, 7 was returned.
If an overflow or underflow occurs, ... the return value is clamped according to the following table.
You're not in that case either.
So strtol didn't fail. Inspecting errno is meaningless. Function that are documented to set errno on failure will do so, in case of failure. When no failure happened, the value of errno is "morally" undefined. Don't inspect it.
strtol is a special case though. POSIX requires the following:
These functions shall not change the setting of errno if successful.
So your example should be ok. Except that you're calling a function between the strtol call and your inspection of errno. If you're 100% sure that that function will not itself change errno, or call another function that might set it, then you'd be ok in this very specific case (a function documented not to alter errno in case of success - this is not the norm). Apparently that's not the case though. NSLog will very likely use some system calls at some point, and those (in general) have no guarantee of not altering errno.

Related

Where does a segmentation fault occur if the debugger points to a function definition?

To elaborate, I am currently writing a program that requires a function that is provided by the professor. When I run the program, I get a segmentation fault, and the debugger I use (gdb) says that the segmentation fault occurred at the definition of the function that, like I said, was provided by the professor.
So my question here is, is the definition itself causing the fault, or is it somewhere else in the program that called the function causing the fault?
I attempted to find a spot in the program that might have been leading to it, such as areas that might have incorrect parameters. I have not changed the function itself, as it is not supposed to be modified (as per instructions). This is my first time posting a question, so if there is any other information needed, please let me know.
The error thrown is as follows:
Program received signal SIGSEGV, Segmentation fault. .0x00401450 in Parser::GetNextToken (in=..., line=#0x63fef0: 1) at PA2.cpp:20 20 return GetNextToken(in, line);
The code itself that this is happening at is this:
static LexItem GetNextToken(istream& in, int& line) {
if( pushed_back ) {
pushed_back = false;
return pushed_token;
}
return GetNextToken(in, line);
}
Making many assumptions here, but maybe the lesson is to understand how the stack is affected by a function call and parameters. Create a main() function, that call the professor's provided function and trace the code using dbg, looking at the stack.

pthread_create return int value of -1; I am not sure what is this error code is

I am new to pthread_create and posix threads, I tried to develop a multi-thread program using pthread_create, but it fails with return value equal to -1. I tried to search what is this error code, but could not find any? Does anyone know what this return code (-1) means?
According to POSIX programming Manual, the return value for the pthread_create functions is:
If successful, the pthread_create() function shall return zero; otherwise, an error number shall be returned to indicate the error.
And the list of possible errors are non-negative.
But, for IBM z/OS, for example, the return value can be -1:
If successful, pthread_create() returns 0.
If unsuccessful, pthread_create() returns -1 and sets errno to one of the following values:
So, I suggest:
provide more context on what's the environment and standard library you use
check the errno variable - it should contain the error code

Passing Data through the Stack

I wanted to see if you could pass struct through the stack and I manage to get a local var from a void function in another void function.
Do you guys thinks there is any use to that and is there any chance you can get corrupted data between the two function call ?
Here's the Code in C (I know it's dirty)
#include <stdio.h>
typedef struct pouet
{
int a,b,c;
char d;
char * e;
}Pouet;
void test1()
{
Pouet p1;
p1.a = 1;
p1.b = 2;
p1.c = 3;
p1.d = 'a';
p1.e = "1234567890";
printf("Declared struct : %d %d %d %c \'%s\'\n", p1.a, p1.b, p1.c, p1.d, p1.e);
}
void test2()
{
Pouet p2;
printf("Element of struct undeclared : %d %d %d %c \'%s\'\n", p2.a, p2.b, p2.c, p2.d, p2.e);
p2.a++;
}
int main()
{
test1();
test2();
test2();
return 0;
}
Output is :
Declared struct : 1 2 3 a '1234567890'
Element of struct undeclared : 1 2 3 a '1234567890'
Element of struct undeclared : 2 2 3 a '1234567890'
Contrary to the opinion of the majority, I think it can work out in most of the cases (not that you should rely on it, though).
Let's check it out. First you call test1, and it gets a new stack frame: the stack pointer which signifies the top of the stack goes up. On that stack frame, besides other things, memory for your struct (exactly the size of sizeof(struct pouet)) is reserved and then initialized. What happens when test1 returns? Does its stack frame, along with your memory, get destroyed?
Quite the opposite. It stays on the stack. However, the stack pointer drops below it, back into the calling function. You see, this is quite a simple operation, it's just a matter of changing the stack pointer's value. I doubt there is any technology that clears a stack frame when it is disposed. It's just too costy a thing to do!
What happens then? Well, you call test2. All it stores on the stack is just another instance of struct pouet, which means that its stack frame will most probably be exactly the same size as that of test1. This also means that test2 will reserve the memory that previously contained your initialized struct pouet for its own variable Pouet p2, since both variables should most probably have the same positions relative to the beginning of the stack frame. Which in turn means that it will be initialized to the same value.
However, this setup is not something to be relied upon. Even with concerns about non-standartized behaviour aside, it's bound to be broken by something as simple as a call to a different function between the calls to test1 and test2, or test1 and test2 having stack frames of different sizes.
Also, you should take compiler optimizations into account, which could break things too. However, the more similar your functions are, the less chances there are that they will receive different optimization treatment.
Of course there's a chance you can get corrupted data; you're using undefined behavior.
What you have is undefined behavior.
printf("Element of struct undeclared : %d %d %d %c \'%s\'\n", p2.a, p2.b, p2.c, p2.d, p2.e);
The scope of the variable p2 is local to function test2() and as soon as you exit the function the variable is no more valid.
You are accessing uninitialized variables which will lead to undefined behavior.
The output what you see is not guaranteed at all times and on all platforms. So you need to get rid of the undefined behavior in your code.
The data may or may not appear in test2. It depends on exactly how the program was compiled. It's more likely to work in a toy example like yours than in a real program, and it's more likely to work if you turn off compiler optimizations.
The language definition says that the local variable ceases to exist at the end of the function. Attempting to read the address where you think it was stored may or may produce a result; it could even crash the program, or make it execute some completely unexpected code. It's undefined behavior.
For example, the compiler might decide to put a variable in registers in one function but not in the other, breaking the alignment of variables on the stack. It can even do that with a big struct, splitting it into several registers and some stack — as long as you don't take the address of the struct it doesn't need to exist as an addressable chunk of memory. The compiler might write a stack canary on top of one of the variables. These are just possibilities at the top of my head.
C lets you see a lot behind the scenes. A lot of what you see behind the scenes can completely change from one production compilation or run to the next.
Understanding what's going on here is useful as a debugging skill, to understand where values that you see in a debugger might be coming from. As a programming technique, this is useless since you aren't making the computer accomplish any particular result.
Just because this works for one compiler doesn't mean that it will for all. How uninitialized variables are handled is undefined and one computer could very well init pointers to null etc without breaking any rules.
So don't do this or rely on it. I have actually seen code that depended on functionality in mysql that was a bug. When that was fixed in later versions the program stopped working. My thoughts about the designer of that system I'll keep to myself.
In short, never rely on functionality that is not defined. If you knowingly use it for a specific function and you are prepared that an update to the compiler etc can break it and you keep an eye out for this at all times it might be something you could explain and live with. But most of the time this is far from a good idea.

Why is sem_open returning invalid pointer in iOS?

I have been stuck into this for quite sometime now. Have a legacy code (in C) that worked on some linux flavors. I am trying to port it on to iOS. I am running the app on iPhone 6.1 simulator
I am trying to use semaphores, by opening one as:-
sem_t * ptr_sem = NULL;
ptr_sem = sem_open("robin", O_CREAT , S_IXUSR | S_IRGRP, 0);
if (ptr_sem == SEM_FAILED) {
printf("\nerror number:%d", errno);
return -1;
} else {
printf("\n semaphore creation errno: %d", errno);
return 0;
}
This code returns 0 every time it is run. It is worth noting that for every new semaphore name, errno is 22 (EINVAL) for the first time, and for all subsequent sem_open() attempts (even after closing the simulator), errno is set to 13 (EACCES). Also, the return value of the pointer returned is an invalid memory address (0x000..5). I have checked some similar questions above - tried doing an unlink() before open(), but it also didn't work for me.
Can anyone let me know what is the problem in the above code?
On Linux flavors, the semaphore name passed to sem_open() is supposed to be "/somename". So, in your source code, the string "robin" is not correct. It should be "/robin". Nevertheless, the EINVAL return code would only appear if:
either the initial value (4th parameter) is bigger than SEM_VALUE_MAX
or the name (1st parameter) contains only "/" characters.
The problem likely comes from the 3rd parameter (access mode). You specify the creation of a semaphore (in the lower layers, this is a file creation in the file system) but the mode is set to "S_IXUSR | S_IRGRP" that is to say execute permission for the owner and read permission for the group. This is incoherent as the owner will need to read and write into the file. Internally, this triggers the creation of a file with the following parameters:
fd = open (tmpfname, O_RDWR | O_CREAT | O_EXCL, S_IXUSR | S_IRGRP);
The preceding may explain why you also get EACESS error.

How do you handle pthread_mutex_unlock failures?

Assuming a thread successfully calls pthread_mutex_lock, is it still possible that a call to pthread_mutex_unlock in that same thread will fail? If so, can you actually do something about it besides abort the thread?
if(pthread_mutex_lock(&m) == 0)
{
// got the lock, let's do some work
if(pthread_mutex_unlock(&m) != 0) // can this really fail?
{
// ok, we have a lock but can't unlock it?
}
}
From this page, possible errors for pthread_mutex_unlock() are:
[EINVAL]
The value specified by mutex does not refer to an initialised
mutex object.
If the lock succeeded then this is unlikely to fail.
[EAGAIN]
The mutex could not be acquired because the maximum number of
recursive locks for mutex has been exceeded.
Really? For unlock?
The pthread_mutex_unlock() function may fail if:
[EPERM]
The current thread does not own the mutex.
Again, if lock succeeded then this also should not occur.
So, my thoughts are if there is a successful lock then in this situation unlock should never fail making the error check and subsequent handling code pointless.
Well before you cry "victory". I ended up on this page looking for a reason why one of my programs failed on a pthread_mutex_unlock (on HP-UX, not Linux).
if (pthread_mutex_unlock(&mutex) != 0)
throw YpException("unlock %s failed: %s", what.c_str(), strerror(errno));
This failed on me, after many million happy executions.
errno was EINTR, although I just now found out that I should not be checking errno, but rather the return value. But nevertheless, the return value was NOT 0. And I can mathematically prove that at that spot I do own a valid lock.
So let's just say your theory is under stress, although more research is required ;-)
From the man page for pthread_mutex_unlock:
The pthread_mutex_unlock() function may fail if:
EPERM
The current thread does not own the mutex.
These functions shall not return an error code of [EINTR].
If you believe the man page, it would seem that your error case cannot happen.

Resources