Under what conditions can lua_close raise a Segmentation Fault error? - c

I'm talking about the Lua-C API. A call to lua_close(lua_State *) results in a segmentation fault, even if the state is valid. How do I know the state is valid? Because I've used it correctly up to that point.
I'd post the source but it's too long and I'm not sure it would be helpful. It simply throws a segmentation fault error at me and I have no clue why. The Lua stack is empty before the call. Can somebody help me?

The Lua C API should never result in a segmentation fault. If the segfault happens when calling lua_close, the most probable reason is that some userdata with custom __gc metamethods are failing. From the documentation of lua_close:
Destroys all objects in the given Lua state (calling the corresponding garbage-collection metamethods, if any)
The best way to determine what is the reason for these segfaults is run gdb and get a backtrace when it happens. If you compile your library with debug symbols, you should get exactly to the place that causes errors.

You say that the Lua stack is empty before the call. But is the function to be called on the stack? It should be, even if you call lua_call(L,0,0). Try also rebuilding Lua with API assertions on. It may give you a better error message.

Related

how to quickly locate the function which firstly returns a specific error code in gdb?

Assume I have a long call-stack. My upper level function returns a error code such as ERROR_INTERNAL(it's int type). I can see many return ERROR_INTERNAL; in source code, but don't know which one generate current error.
I debug it with gdb, and want to quickly know which down-level function is the first one to throw this error. I'm not familiar with the code, and I don't have time to delve into it.
Anyone who knows how to use gdb functions such as conditional breakpoints to locate the function ?

cmocka free operation and catching exceptions

I started my adventure with cmocka library, and I have two questions.
Is it possible to find out if free() operation was made correctly? I mean, I would like to test function which is cleaning up tree structure. I've read about test_free(), but honestly I don't understand idea behind that.
The second thing is case of catching standard library exceptions. I know about function expect_assert_failure, but how to use it? For example I would to do something what will throw segmentation fault, but I would like to pass test anyway.
You need to add
#define UNIT_TESTING 1
before you include the cmocka.h header file, then malloc, realloc and free get overridden and will warn you about memory leaks.
expect_assert_failure() if for checking that an assert() condition is really hit.
I'd suggest just doing an additonal test with valgrind.
valgrind --error-exitcode=1 ./test
Without the option valgrind would always return the same exit code returned by your test program. This way if your test program succeeds, but valgrind's memory check reveals errors, it will return 1 to indicate an error.

Easiest way to locate a Segmentation Fault

I encountered my first Segmentation Fault today (newbie programmer). After reading up on what a segmentation fault is (Thanks for all of the helpful info on this site, as well as Wikipedia's lengthy explanation), I'm trying to determine the easiest way to go about finding where my fault is occuring. It's written in C and the error is occuring on a *NIX based system (I'm not sure which one to be honest... 99% sure it's Linux). I can't exactly post my code as I have numerous files that I'm compiling that are all quite lengthy. I was just hoping for some best practices you have all observed. Thanks for your help.
P.s. I'm thinking the error is coming from dereferencing a NULL pointer or using an uninitialized pointer. However, I could definitely be wrong.
Use a debugger, such as gdb or if this is not applicable a strace tool to get a better insight into where the segfault occurs.
If you use gcc, make sure you compile with -g switch to include debugging information. Then, gdb will show you the exact location in a source code where it segfaults.
For example, if we have this obvious segfaulty program:
new.c
#include <stdio.h>
int main()
{
int *i = 0x478734;
printf("%d", *i);
}
We compile it with gcc -g new.c -o new and then run the gdb session with gdb new:
We issue the run command in the interactive session and the else is clear:
(gdb) run
Starting program: /home/Tibor/so/new
[New Thread 9596.0x16a0]
[New Thread 9596.0x1de4]
Program received signal SIGSEGV, Segmentation fault.
0x0040118a in main () at new.c:6
6 printf("%d", *i);
(gdb)
As DasMoeh and netcoder have pointed out, when segfault has occured, you can use the backtrace command in the interactive session to print a call stack. This can aid in further pinpointing the location of a segfault.
The easiest way is to use valgrind. It will pinpoint to the location where the invalid access occours (and other problems which didn't cause crash but were still invalid). Of course the real problem could be somewhere else in the code (eg: invalid pointer), so the next step is to check the source, and if still confused, use a debugger.
+1 for Tibors answer.
On larger programs or if you use additional libraries it may also be useful look at the backtrace with gdb: ftp://ftp.gnu.org/pub/old-gnu/Manuals/gdb/html_node/gdb_42.html
I reopen this posts for people passing here since I've just corrected a segfault I've made using gcc.
You should consider using the flag -fsanitize=address which can sometimes highlight your segfault with high precision.

segmentation fault after main returns

I have a long program in c over Linux, that gives me segmentation fault after main returns.
Its a long program, so I cant post it. So can you help me what can make such error?
Thank You.
Wow, Those answers came really fast. Thank you all.
I think i worked it out, i forgot to malloc a string and used it as buffer.
Now that I've malloced it, it does not signal me with a segmentation fault.
Once again, thank you all.
Guess: you might be accidentally corrupting the stack in main so it's lost the return address. Do you have a string buffer there that you could be overrunning?
If not, you should try:
running the program under valgrind
debugging the program with gdb to catch the crash and see where you are at that point; you can also debug the core file dumped
It might help to install glibc-debug packages if your distro has them since you'll be in glibc code at that point.
Use GDB and print stack trace on SIGSEGV signal. Then at least post that here so we can be a little bit more helpful.
Provided you compiled with:
$ gcc -g prog.c -o prog
Then run it under GDB:
$ gdb ./prog
gdb> r
When you get SIGSEGV signal (Segmentation Fault), do this:
gdb> bt
Then see what's on the stack trace to see what is causing the segmentation fault.
If the segmentation fault arises after main() returns, it usually means that a global defined thing went wrong. It is hard to help you with so little info. Send us more info !
my2c
If it's after main() returns, then according to the Standard all destructors have been run (although I wouldn't put it past an implementation to fudge this some), unless the function atexit() has been used. That function registers a function that will be called after main() returns, effectively (if I'm reading 3.6.3 aright). You might check to see if there is an atexit in your program somewhere, if only for completeness.
Depending on what you mean by "after main returns", you may be running destructors for static objects when the program crashes. Check those. (Also, post what you observed that made you think it was after main() returned. You could be wrong there.)
If not, then you've invoked undefined behavior somewhere, very likely in corrupting the stack somehow. See Rup's answer for suggestions there.

How to find where error is

How can I find where the error occurs?
In C language, the return value means what error occurs,
such as failure to open file or memory allocation.
There is no information where the error occurs.
For example, function 'foo' calls A,B,C,D.
If foo returns an error value, it might be return value of A or B or C or D.
I cannot find what function returns error.
I have to run debugger or add some codes to find what function returns error.
Yes, you'll have to use a debugger or add extra code to display some output. Also, make sure you look at the pre-conditions for the function you call (if there are any) - make sure that you obey what it demands before calling it.
I think you've answered your question, you need to use a debugger to find out.
Maybe add some breakpoint, look if the error occurs always or only sometimes, and in the same place.
C library functions like fopen() set errno to give you a bit more diagnostic information. You could use a similar strategy. But if you don't program in some way of getting extra information out like that, you are stuck with the debugger.
Design an appropriate error handling that provides the informations you need. Then write your functions around this design. Using the return values is just one of many possibilities to do this, but obviously not enough for your specific requirements.
What error occurs is a clue for where it occurs: if A can return only error #5, B only #42, C only #3 and D only #56, whenever foo returns #5, you know that it comes from A.
If error codes overlap over different functions, you can get other clues from your inputs and your outputs: if D either displays a message or issues an error #5, whenever foo returns #5 and the message gets displayed, you know that error comes from A.
If error code, inputs and output are not enough to retrieve error location, you have to increase observability of your program. Some solutions are:
add debug info and use a debugger
add logs that you can activate or inhibit at will
select unique error codes so that what error occurs identifies where it occurs as well

Resources