Exact line number for C error? - c

I have a compiled version of the game 'Rogue', as well as its source code. Sometimes, at seemingly random times, the game will put up a non-descriptive error message.
Is there a way of compiling the source in an IDE, and getting the specific line number where the program fails when it is run in the IDE?

If you can edit the error messages to:
printf (stderr, "Blah error at %s (%d)\n", __FILE__, __LINE__);
you can get the exact location.
Since editing all the messages would be a big pain, I'd suggest you define a macro that does it:
#define MYERR(...) do { \
printf ("# %s (%d): ", __FILE__, __LINE__); \
printf (__VA_ARGS__); \
} while (0)
Replace all error messages calls to invoke this macro (thats much easier than appending to each message).

Related

Is there any way to get the source code line number in C code in run time? [duplicate]

This question already has answers here:
C/C++ line number
(10 answers)
Closed 6 years ago.
Is there any way to get the source code line number in C code in run time?
The thought behind it is, suppose a software is made in plain C language. the .exe file is distributed to a user who knows nothing about C. Now if there is any error, the user can see the line number and report the error to the manufacturer so that the debugging can be done at manufacturer site. I just to debug the run time errors and get the corresponding line numbers in the source code while running it. I am a beginner in these stuffs.
If you are using the GCC compiler, you can use the Standard Predefined Macro - __LINE__ as a line number placeholder.
The compiler will fill in the line number while compiling.
Eg :-
printf("%d",__LINE__);
Use gdb instead. But I guess it will work:
if(someThingsWrong())
printf("wrong at line number %d in file %s\n", __LINE__, __FILE__);
You can use the built-in macros __LINE__ and __FILE__, which always expand to the current file name and line number.
#include <stdio.h>
int main(int argc, char *argv[])
{
if(argc<2)
{
printf("Error: invalid arguments (%s:%d)\n", __FILE__, __LINE__);
return 0;
}
printf("You said: %s\n", argv[1]);
return 0;
}

multi process failure - finding last function being used

I am working on a complex code that use multi-process techniques.
I have 1 simulation process and 3 child processes.
The code compile with no errors and the software usually run OK and give good result. In some case, usually in long simulation runs, one of the child process send sigchld and the program is terminated.
Is there a way to force the child process to print the name of the last function being called before the error?
Is there a way to force the child process to print the line number of the last line being used before the error?
I am working with eclipse 3.8.1 under Ubuntu and the code is regular C.
I don't know if you can do what you are asking, but I would suggest adding debug statements using a macro such as:
#define DBG_ENABLED 1
#if DBG_ENABLED
#define DBG(...) \
do { \
printf("%s(%d) %s(): ", __FILE__, __LINE__, __func__); \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
#else
#define DBG(...)
#endif
Then for example:
void YourFunction(int x, int y) {
DBG("x=%d y=%d", x, y);
. . .
DBG("ok");
}
This allows you to see what your program is doing, and it should help pinpoint the location of the problem. Then you can set DBG_ENABLED to 0 to remove the debug from your executable.
(Probably better to use fprintf() to print to a file rather than printf() if you are running long simulations.)

Automatically inserting filename & line number in logging statements of a C program

I am writing a program for an embedded ARM processor in C. I would like to see the source filename and line number in the logging statements.
As the compiled code has no knowledge of line numbers and source files, I am looking for ways to have this inserted automatically before / during the compile process.
Are there any standard tools or compiler features that I can use for this?
I am using GCC.
For example:
This is what I would write in the source file:
log("<#filename#> <#linenumber#> : Hello World");
This is what would actually get compiled:
log("Foobar.c 225 : Hello World");
Typically you'd do something like this:
// logging function
void log(const char * file, const int line, const char *msg)
{
fprintf(stderr, "%s:%d: %s\n", file, line, msg);
}
// logging macro - passes __FILE__ and __LINE__ to logging function
#define LOG(msg) do { log(__FILE__, __LINE__, msg) } while (0)
Then when you want to log something:
LOG("We made it to this point!");
which will then generate a log message such as:
foo.c:42: We made it to this point!
There is a standard set of predefined macros as part of the preprocessor: https://gcc.gnu.org/onlinedocs/gcc-4.9.0/cpp/Standard-Predefined-Macros.html
The macros you want to use are __FILE__ and __LINE__ which are the file name and line numbers.

look for a API/function which is like assert() without abort in C

the assert() function can print the error and where the error happens, but it will also abort the function.
I want to have a assert() function without aborting. I only hope to print the error, the name of the file where error happens, etc.
is there such a API or source snippets in C?
thanks!
Cunit has an assert that will either be fatal (quits) or not (will continue).
http://cunit.sourceforge.net/doc/writing_tests.html#tests
So if I'm reading this right, your question is basically "How do I print the file name and line number?"
Simple, use
__FILE__, __LINE__
If you want, create your own macro like
#define MY_ASSERT(x) if(x) printf("Assertion! Line: %d File: %s \n", __LINE__, __FILE__)
THere are other useful predefined macros too. http://gcc.gnu.org/onlinedocs/gcc-3.1/cpp/Standard-Predefined-Macros.html
First of all lets see what assert is
the documentation says
assert() is implemented as a macro
and now lets see the actual implementation of assert
something like this
((x = 0) ? (void) (0) : __assert_fail ("x = 0", "t.c", 9, __PRETTY_FUNCTION__));
well in your case you may not want the expression below
__assert_fail ("x = 0", "t.c", 9, __PRETTY_FUNCTION__))
now what we can do here now is
something like this
#define MY_ASSERT(expr) \
(expr ? (void) (0) : printf("something"));
int main(int argc, char *argv[]){
MY_ASSERT(argc == 0)
}
hope this helps
This is called an exception, and it is a construct that is available in languages like C++ with an optimized implementation. With exceptions, you can exit any function anywhere you want, and end up anywhere up the call stack, without a single memory leak. Of course, this will require you code to be exception safe.
In C, you'd need to hack around with goto, setjmp, longjmp, which would basically be a bad version of C++ exceptions.
See e.g. http://en.cppreference.com/w/cpp/language/exceptions

Is this the correct behaviour of __LINE__

15 ERROR_MACRO("Error is in %s on line %d\n",
16 __FILE__, __LINE__);
I am getting following output:
Error is in tmp.c on line 16
I am getting same output, even if I use the above line in this form :
15 ERROR_MACRO("Error is in %s on line %d\n", \
16 __FILE__, __LINE__);
Shouldn't I get "line 15" instead of "line 16" ?
What should I do to get "line 15" ?
__LINE__ always expands to the exact line number that it appears on. It's up to the compiler how it reports errors for code that spans multiple lines, but most compilers go by the line that the statement started on (since most errors cannot be localized to a single character).
There is no macro which can determine what line the current statement appears on, as preprocessing typically occurs before the compiler even starts thinking about statements.
move the ERROR_MACRO to line 15 in your code? __LINE__ is the line number within the current file. There is no (legal) way to change it unless you move your code...
If you insist upon using __LINE__ on the line following the call, then just do:
ERROR_MACRO("Err in %s on line %d\n",
__FILE__, __LINE__ - 1);
Better yet, why don't you just define a macro for your macro:
#define MY_ERR ERROR_MACRO("Err in %s on line %d", __FILE__, __LINE__)
Now you can just call a short MY_ERR; instead of worrying about line length restrictions (which is why you're doing this, I assume).

Resources