When I am using function name as variable mistakenly it is causing abort.
Condition is like this:
hello()
{
}
if(!hello) //this is crashing
{
}
As per my understanding this code should not crash as the function name is a valid address.
Also because of this my data segment is getting corrupted (not able to see any variable in crash inspect).
Related
I was taught that variables within scope are destroyed (freed/de-allocated?) at the instruction generated by the "}" at the end of a scope body. I was about to teach someone the same thing, but I decided to see for myself, what will happen if I change a local variable through a pointer like this:
int main ()
{
int* p = NULL;
if(1)
{
int localvar = 1;
p = &localvar;
}
(*p) = 345;
printf("%i\n", *p);
return 0;
}
Compiled with MinGW-GCC and "-Wall -g -pedantic -w -Wfatal-errors -Wextra" (even though -Wall overrides most flags)
It was very surprising to me that not only a warning was generated, but also no runtime exception was thrown. Instead, everything seems to work just as if I am accessing a global variable.
Can this be explained in a definitive manner to avoid any future misconceptions?
C compilers aren't required to generate an error when you do something like this. That's part of what makes C fast.
That also means that if you do something you're not supposed to do, you can trigger undefined behavior. This essentially means that no guarantees can be made regarding what the program will do. It could crash, it could output strange results, or it could appear to be work properly as in your case.
How UB manifests itself can change by making a seemingly unrelated change, such as adding an unused local variable or a call to printf for debugging.
In this particular case the memory in question hasn't been reserved for some other use so it is still in the valid memory space for the program and hasn't yet been overwritten. But again, you can't rely on that behavior.
For debugging reasons I am trying to print the name of the function that made an illegal memory access (out of range for example).
I have written a SIGSEGV signal handler to print the Instruction Pointer (IP) and the faulted memory address, but I was not able to create a method such that I can get the function name and not the IP.
Is there a way to modify the signature of the signal handler to pass the __ FUNCTION __ variable as an argument or is there another method to do this?
Note: The program is written in C and I trying to do this in a Linux environment.
You can use backtrace and backtrace_symbols_fd to print the function names with call stack.
Check the man pages for backtrace and backtrace_symbols or backtrace_symbols_fd.
An example is here:
http://man7.org/linux/man-pages/man3/backtrace.3.html
I am taking the first dive into the waters of stack memory trace so I need your help. Here is my problem for which I need your tips:
I have two functions: login and logout(). There is one simple condition:
If I call login() to create a session, then somewhere in my program, logout() should be called otherwise there should be an error generated.
I believe that that I can not do it on compile time so I have to do it on runtime(I can be wrong).
The problem is that how do I find out that logout() is called in my program before the main() returns and generate error if it is not called.
I was thinking that at the runtime, Every function that I call after login() should check whether it is the last function call and then look whether the logout() was called ever before or not.
So How would I know at runtime that a certain function is the last function my program called before the main() returns?
Any help would be appreciated.
one way, perhaps not the nicest, is to use a variable loggedIn = 1, and pass a reference to it so logout() can set it to zero. check that it's zero before return from main().
after a function returns, its address has already been popped from the stack.
In one of Apple's header files for libdispatch, queue.h, the following warning appears:
// The declaration of a block allocates storage on the stack.
// Therefore, this is an invalid construct:
dispatch_block_t block;
if (x) {
block = ^{ printf("true\n"); };
} else {
block = ^{ printf("false\n"); };
}
block(); // unsafe!!!
// What is happening behind the scenes:
if (x) {
struct Block __tmp_1 = ...; // setup details
block = &__tmp_1;
} else {
struct Block __tmp_2 = ...; // setup details
block = &__tmp_2;
}
// As the example demonstrates, the address of a stack variable is
// escaping the scope in which it is allocated. That is a classic C bug.
Try as I may, I cannot come up with a test case that exemplifies this bug. I can create blocks that are instantiated on the stack, but they (seem to) always appear at unique addresses on the stack, even when out of scope with respect to each other.
I imagine that the answer to this is simple, but it escapes me. Can anyone fill the gaps in my (limited) understanding?
EDIT: I've seen this response, but I don't quite understand how that instance can translate to my example posted above. Can someone show me an example using if constructs?
In order to crash a stack closure inside a function:
You need to make sure that the closure is indeed a stack closure. As of Apple Clang 2.1, a closure that doesn’t reference variables in its current context (like the one in queue.h) is realised as a global closure. This is an implementation detail that can vary amongst different compilers/compiler versions;
The compiler must emit code that effectively reuses/rewrites the stack area where the closure once lived. Otherwise, every object inside that function lives in a different address in the function stack frame, which means you won’t get a crash inside that function. It seems that Apple Clang 2.1 doesn’t reuse stack memory addresses. GCC 4.6 can reuse them, but it doesn’t support closures.
Since Apple Clang 2.1 doesn’t reuse addresses in a function stack frame and GCC 4.6 doesn’t support closures, from what I can tell it’s not possible to make this particular example — inside a function, invoke an out of scope stack closure — crash.
I wrote a more detailed text about this on my blog.
I have the following structure:
struct sys_config_s
{
char server_addr[256];
char listen_port[100];
char server_port[100];
char logfile[PATH_MAX];
char pidfile[PATH_MAX];
char libfile[PATH_MAX];
int debug_flag;
unsigned long connect_delay;
};
typedef struct sys_config_s sys_config_t;
I also have a function defined in a static library (let's call it A.lib):
sys_config_t* sys_get_config(void)
{
static sys_config_t config;
return &config;
}
I then have a program (let's call it B) and a dynamic library (let's call it C). Both B and C link with A.lib. At runtime B opens C via dlopen() and then gets an address to C's function func() via a call to dlsym().
void func(void)
{
sys_get_config()->connect_delay = 1000;
}
The above code is the body of C's func() function and it produces a segmentation fault when reached. The segfault only occurs while running outside of gdb.
Why does that happen?
EDIT: Making sys_config_t config a global variable doesn't help.
The solution is trivial. Somehow, by a header mismatch, the PATH_MAX constant was defined differently in B's and C's compilation units. I need to be more careful in the future. (facepalms)
There is no difference between the variable being a static-local, or a static-global variable. A static variable is STATIC, that means, it is not, on function-call demand, allocated on the stack within the current function frame, but rather it is allocated in one of the preexisting segments of the memory defined in the executable's binary headers.
That's what I'm 100% sure. The question, where in what segment they exactly placed, and whether they are properly shared - is an another problem. I've seen similar problems with sharing global/static variables between modules, but usually, the core of the problem was very specific to the exact setup..
Please take into consideration, that the code sample is small, and I worked on that platforms long time ago. What I've written above might got mis-worded or even be plainly wrong at some points!
I think, that the important thing is that you are getting that segfault in C when touching that line. Setting an integer field to a constant could not have failed, never, provided that target address is valid and not write-protected. That leaves two options:
- either your function sys_get_config() has crashed
- or it has returned an invalid pointer.
Since you say that the segfault is raised here, not in sys_get_config, the only thing left is the latter point: broken pointer.
Add to the sys_get_config some trivial printf that will dump the address-to-be-returned, then do the same in the calling function "func". Check whether it not-null, and also check if within sys_get_config it is the same as after being returned, just to be sure that calling conventions are proper, etc. A good idea for making a double/triple check is to also add inside the module "A" a copy of the function sys_get_config (with different name of course), and to check whether the addresses returned from sys_get_config and it's copy are the same. If they are not - something went very wrong during the linking
There is also a very very small chance that the module loading has been deferred, and you are trying to reference a memory of a module that was not fully initialized yet.. I worked on linux very long time ago, but I remember that dlopen has various loading options. But you wrote that you got the address by dlsym, so I suppose the module has loaded since you've got the symbol's final address..