multi process failure - finding last function being used - c

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.)

Related

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

C preprocessor using the closing bracket of a parent macro

I have this code which works:
#include <stdio.h>
#define A(x) x B
#define B(x) C(x,
#define C(x,y) y x)
int main( void ) {
printf( A("1") ("2") "3" );
}
It prints 132 (the point of the A macro is to swap the thing which follows its parameters in brackets with everything after that until another closing bracket)
But if I use that within another macro:
#define Z(x) x
printf( Z( A("1") ("2") "3" ) );
I get the compile error "Unterminated function-like macro invocation".
I realise that this happens because the compiler is trying to process the arguments of Z independently, but I need to use its closing bracket as a marker. Is there a way I can make this work within macros? Changing the calling syntax isn't really an option.
p.s. Before I get any responses talking about what an awful thing this is to do, rest assured: this is not for real code. It is a problem which came up while making a toy program which uses define to simulate a new language inside C.
The easiest way to see what's going on is to change the test case a little.
#define A(x) x B
#define B(x) C(x,
#define C(x,y) y x] /* note close square bracket instead of close paren */
Y(A(1)(2)3)
preprocesses to Y(1 3 2]. This is because an intermediate stage of expansion looked like
Y(1 C(2,3)
at which point C ate the close paren that appeared to belong to Y in the original text and replaced it with a close bracket.
Now, what happens differently if A(1)(2)3 is inside a macro argument?
#define Z(x) x
Z(A(1)(2)3)
Because of argument prescan, the analogous intermediate stage of expansion is not
Z(1 C(2,3)
but rather
1 C(2,3
with Z squirrelled away on a hidden "pending expansions" stack. The preprocessor is, in effect, enforcing the textual appearance that that final close paren belongs to Z, and C is not allowed to borrow it.
The least-invasive way I can think of to achieve your original goal is
#define _A(x) x B
#define B(x) C(x,
#define C(x,y) y x)
#define Z(x) ZZ((_##x))
#define ZZ(x) ZZZ x
#define ZZZ(x) [x]
Z(A(1)(2)3)
preprocesses to [1 3 2]. We use the token paste operator to prevent Z's argument from being prescanned, so we can add a temporary extra set of parentheses for use by C. ZZ and ZZZ then strip them off again. The catch is that it's an error if you don't paste x with something, so we have to add a leading underscore to the definition of A, and it will be an error if the first token of Z's argument is ever not something that can be token-pasted after an underscore.
You might want to consider using M4 instead of trying to shoehorn this into the C preprocessor.
eclipse cdt is excellent to debug your questions. for eclipse, just hover over a macro to get started. here is detialed info on it:
C/C++ Software Development with Eclipse >> 2.1.7. Macro Expansion
for your second macro, eclipse shows the following:
int main (void) {
printf( Z( A("1") ("2") "3" ) );
}
Spotting the Error
Notice in the expansion #3 C("2", "3" just 'disappears. I take this as CDT's way of saying 'unterminated argument list'. Whatever the case for it disappearing, this is the method I prefer to take when debugging macros.
Using this tool makes it clear that in Expansion#2 (third image) we have an unterminated set of brackets, thus locating the error.
Understanding a Solution
After fiddling around a bit using this tool, I think this is what you were after:
printf( Z( (A("1") ("2") "3") ) );
yields (using gcc -E main.c -c)
printf( ("1" "3" "2") );
This is about the order in which the macros are processed. The simplest solution is to add additional parentheses around the Z argument.
printf( Z( (A("1")("2") "3")) );

Exact line number for C error?

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).

Why are these C macros not written as functions?

I'm studying the code of the netstat tool (Linux), which AFAIK mostly reads a /proc/net/tcp file and dowa pretty-printing out of it. (My focus is on the -t mode right now.)
I'm a bit puzzled by the coding style the authors have chosen:
static int tcp_info(void)
{
INFO_GUTS6(_PATH_PROCNET_TCP, _PATH_PROCNET_TCP6, "AF INET (tcp)", tcp_do_one);
}
where
#define INFO_GUTS6(file,file6,name,proc) \
char buffer[8192]; \
int rc = 0; \
int lnr = 0; \
if (!flag_arg || flag_inet) { \
INFO_GUTS1(file,name,proc) \
} \
if (!flag_arg || flag_inet6) { \
INFO_GUTS2(file6,proc) \
} \
INFO_GUTS3
where
#define INFO_GUTS3 \
return rc;
and
#if HAVE_AFINET6
#define INFO_GUTS2(file,proc) \
lnr = 0; \
procinfo = fopen((file), "r"); \
if (procinfo != NULL) { \
do { \
if (fgets(buffer, sizeof(buffer), procinfo)) \
(proc)(lnr++, buffer); \
} while (!feof(procinfo)); \
fclose(procinfo); \
}
#else
#define INFO_GUTS2(file,proc)
#endif
etc.
Clearly, my coding sense is tilting and says "those should be functions". I don't see any benefit those macros bring here. It kills readability, etc.
Is anybody around familiar with this code, can shed some light on what "INFO_GUTS" is about here and whether there could have been (or still has) a reason for such an odd coding style?
In case you're curious about their use, the full dependency graph goes like this:
# /---> INFO_GUTS1 <---\
# INFO_GUTS --* INFO_GUTS2 <----*---- INFO_GUTS6
# î \---> INFO_GUTS3 <---/ î
# | |
# unix_info() igmp_info(), tcp_info(), udp_info(), raw_info()
Your sense that "those macros should be functions" seems correct to me; I'd prefer to see them as functions.
It would be interesting to know how often the macros are used. However, the more they're used, the more there should be a space saving if they're a real function instead of a macro. The macros are quite big and use (inherently slow) I/O functions themselves, so there isn't going to be a speed-up from using the macro.
And these days, if you want inline substitution of functions, you can use inline functions in C (as well as in C++).
You can also argue that INFO_GUTS2 should be using a straight-forward while loop instead of the do ... while loop; it would only need to check for EOF once if it was:
while (fgets(buffer, sizeof(buffer), procinfo))
(*proc)(lnr++, buffer);
As it is, if there is an error (as opposed to EOF) on the channel, the code would probably go into an infinite loop; the fgets() would fail, but the feof() would return false (because it hasn't reached EOF; it has encountered an error - see ferror()), and so the loop would continue. Not a particularly plausible problem; if the file opens, you will seldom get an error. But a possible problem.
There is no reason why. The person who wrote the code was likely very confused about code optimizations in general, and the concept of inlining in particular. Since the compiler is most likely GCC, there are several ways to achieve function inlining, if inlining was even necessary for this function, which I very much doubt.
Inlining a function containing file I/O calls would be the same thing as shaving an elephant to reduce its weight...
It reads as someones terrible idea to implement optional IPv6 support. You would have to walk through the history to confirm, but the archive only seems to go back to 1.46 and the implied damage is at 1.20+.
I found a git archive going back to 1.24 and it is still there. Older code looks doubtful.
Neither BusyBox or BSD code includes such messy code. So it appeared in the Linux version and suffered major bit rot.
Macros generate code: when it is called, the whole macro definition is expanded at the place of the call. If say, INFO_GUTS6 were a function, it wouldn't be able to declare, e.g., the buffer variable which would subsequently be usable by the code that follows the macro invocation. The example you pasted is actually very neat :-)

Resources