String Manipulation in C, <optimized out> error - c

I was solving cs50x pset6 Webserver problem and I would be very grateful if someone could help me.
Can anyone explain what is happenning below in gdb(also in source code itself) please?
Optimized out and Gone String Variable
The problem is that manipulation string variables is needed in this problem set, but somehow I lose them whenever new variable comes up(along).
I tried compiling differently as suggested by some sources e.g. https://cs50.stackexchange.com/questions/9033/variable-optimized-out-eventhough-it-will-be-used-later .
But nothing has changed even I tried other solutions.
So guys I will appreciate if you can help me to fix this issue.
Here is my source code(lines 151-391): http://codepaste.net/2uipag
Edit: This error is affecting not just debugging mode, but the program itself isn't giving intended result. Basically:
Line ="GET /cat.html HTTP/1.1"
absolute_path="/cat.html" (extracted using strncpy())
root="/home/jharvard/pset6/public"
path= root along with absolute_path (strcat())
Because absolute_path is optimized out instead of getting "home/jharvard/pset6/public/cat.html" for path variable, I am getting "home/jharvard/pset6/public"
I apologize for being unclear and thank you for assistance.

It is difficult to say what is happening with any specificity, but most likely, at some point after the last use of your line pointer by the function, the optimized version of the program re-uses its storage for something else. If the variable is still in scope at that point then in principle you should still be able to examine its value, but if your program in fact does not examine its value then it makes no difference in program behavior. Except as viewed via a debugger.
If you intend to run your code in a debugger then it is best to compile it (for that purpose) with optimization disabled (option -O0 for many C compilers, including gcc). After you have worked out the problems, compile your final program with whatever optimization level you deem appropriate.

Related

Static variable doesn't initialize to given value

I have a static "init" variable to run a function once on startup, (RTOS) but it seems to initialize to a random value. If I remove the static tag, everything works great. (Except for the obvious issue of it running the init function every pass.) Could anyone give more insight as to why this isn't working or perhaps a better way to achieve this?
Example code:
void ManageStructures()
{
// Variable declarations/definitions
static uint8_t StructInitialized;
// Have also tried "static uint8_t StructInitialized = 0", neither worked
// Function prototypes
void InitStruct();
if (!StructInitialized)
{
StructInitialized= 1;
InitStruct();
}
Test = StructInitialized;
edit: I apologize for the lack of information. This is for a company and I am trying to stay within the bounds of our public information policy. The MCU is a STM32F7 series using the "Ac6 STM32 MCU GCC" toolchain. I am not well versed in compiler operations so it may take me longer to find answers to the compiler or makefile related questions.
edit: It has become clear that this is an issue with the compiler or linker scripts and not my code. That being said, it has also become abundantly clear that I need to learn more about toolchains, linker scripts, and compilers in general before getting to the root of this issue. I'll return to this question once I have become familiar enough to give valuable feedback or answer it myself. Thank you everyone for the feedback and direction!
It is common that embedded systems run with a "minimal startup" code, meaning that they never initialize .bss or .data during start-up. Meaning that if you write something like static int foo = 42;, the code will compile but the variable will never be set.
This isn't standard C compilant, so usually upon project creation you get an option from the IDE to have a "minimal" or "standard" startup.
This likely lies in the so-called "CRT" (C run-time) delivered with your tool chain and not in the RTOS. If you single step your program from where it actually starts (the reset vector) rather than from where main() starts, you'll be able to see exactly what the CRT does and doesn't.
Unfortunately debuggers often use a "dumbed-down mode", since embedded systems programmers are by default assumed to be completely incompetent nowadays. Meaning that they silently insert a breakpoint at main() and run until that point. You might have to "un-dumb" your debugger in order to debug the CRT.

Break for C compilation

I am new to C. I encountered an error message which involves unexpected "}". However, I checked the number of "}" with an editor and indeed they pair up.
Then I wonder if there is a compiler command, so the compilation can stop whatever I want? It will be convenient to have such tool as debug help.
Thank you.
(Edited in 29-10-2015)
I typically write my code with gedit. Nonetheless, since my work is mostly done on cluster, it will be troublesome to transport the files up and down. I must turn to nano, vi or vim which causes difficulty in debugging.
Stopping compilation partway through is rarely a useful feature. You'll want to see all of the errors that may exist in your code so you can fix more that just one at a time.
That said, an error such as a misplaced brace or parenthesis can cascade down and cause several more errors to appear. So if you see a long list of errors that don't seem to make sense when you look at the code, start at the top and fix that, then recompile to see if it took care of any others.
The answer is no compilers are all or nothing.
However, a good editor is recommended. For example, you can match brackets with the % command in vi, or if you have a color editor, you can visually see what's going on. A better IDE would even allow you to hide/show blocks of code, format it with proper indentation, and flag any compilation issues from static rules without actually compiling your code.

regex.h causes exception in VisualStudio 2010

I wanted to show my students how to use regular expresions. As they are learn programming in C, I thought it would be the best to use regex.h from GnuWin32 (http://gnuwin32.sourceforge.net/packages/regex.htm). As an example I tried to run http://www.peope.net/old/regex.html programm, but it causes an exception on the variable holding the regular expression at runtime . The precise error message is:
Run-Time Check Failure #2 – Stack around the variable 'regex' was corrupted
The courius thing is that the example itself is running properly and the regex functions seems to work properly. The error happens after all the important things are over at the point where main() wants to return.
Has anybody an idea of why this error occurs? Could the 64-Bit System I'm using be part of the problem?
Thanks for any advice!

glUseProgramObjectARB invalid operation error

I'm getting an "invalid operation" error when trying to use glUseProgramObjectARB and I have no idea why.
The shader programs are loading correctly, I'm fairly sure. This is shown on glGetInfoLogARB:
Vertex shader was successfully compiled to run on hardware.
Fragment shader was successfully compiled to run on this hardware.
There are no previous openGL errors before this command. So something with this specific command definitely appears to be the issue.
I'm using glew with SDL. I was using GLee before, and getting the same problem.
Reading the documentation I assume it is this error:
GL_INVALID_OPERATION is generated if program could not be made part of current state.
but I'm not sure exactly what could cause such a thing. The command is issued in a working openGL context, as all the previous shader commands work fine. It is not between a "begin" and "end" block.
Really I am stumped as to what it could mean. Perhaps there is some more specific case when the command can't be issued. If anyone knows anything more that would be great.
EDIT:
Solved: oh jesus that was retarded, I was missing a return on one of my function calls elsewhere and so wasn't passing back the program I'd constructed.
Without seeing your code it's hard to know, but since you explicitly mention the results of glCompileShaderARB (times two) but not glLinkProgramARB I will guess that you forgot to glLinkProgramARB (after which, by the way, you can safely glDeleteObjectARB the two shader objects).

debugging c programs

Programming in a sense is easy. But bugs are something which always makes more trouble. Can anyone help me with good debugging tricks and softwares in c?
From "The Elements of Programming Style" Brian Kernighan, 2nd edition, chapter 2:
Everyone knows that debugging is twice
as hard as writing a program in the
first place. So if you're as clever as
you can be when you write it, how will
you ever debug it?
So from that; don't be "too clever"!
But apart from that and the answers already given; use a debugger! That is your starting point tool-wise. You'd be amazed how many programmers struggle along without the aid of a debugger, and they are fools to do so.
But before you even get to the debugger, get your compiler to help you as much as possible; set the warning level to high, and set warnings as errors. A static analysis tool such as lint, pclint, or QA-C would be even better.
Tools for debugging are all well and good and for some classes of error they will just point you straight to the problem. The best tip that I have for debugging is that you need to think about it in the right way. What works for me is the following:
The compiler probably isn't broken. I've been working with C for 25 years now and in all that time it's almost invariably something I'm doing wrong.
Read the error messages. Often I've looked back at the error message and in hindsight realized it was telling me exactly what was wrong.
Read the documentation. Make sure you aren't making assumptions about the language or library that aren't true.
Make a mental model of the problem. I ask myself what needs to be hapening in my code in order for the results I'm seeing to occur. Then add debug statements, assertions or just step through in the debugger (if you can) to see what is really happening.
Talk the problem through with someone else. Just describing it to a a third party often results in a revelation about what might be happening.
Other people will have other ways of approaching debugging, but I find if you have a structured approach to it rather than flailing around changing stuff at random you usually get there and when you do be prepared for the inevitable Why didn't I see that straight away!
Best debugger for C
gdb
Best tools for memory leak checking:
Valgrind
The following are popular debugging tools.
Valgrind
Purify
Duma
Some very simple Tricks/Suggestions
-> Always check that nowhere in your code you have dereferenced a wild/dangling pointer
Example 1)
int main()
{
int *p;
*p=10; //Undefined Behaviour (crash on most implementations)
}
Example 2)
int main()
{
int *p=malloc(sizeof(int));
//do something with p
free p;
printf("%d", *p); ////Undefined Behaviour (crash on most implementations)
}
-> Always initialize variables before using
int main()
{
int k;
for(int i= k;i<10;++i)
^^
Ouch
printf("%d",i");
}
In addition to all the other suggestions (gdb, valgrind, all that), some simple rules when writing the code help a lot when debugging afterwards.
Always use types with the proper
semantics. Unsigned types (best
size_t) for array indices and numbers that represent a cardinal,
ptrdiff_t for pointer differences,
off_t for file offsets etc. enum types for tags and case distinctions.
There is almost no need for the
builtin types int, long, char or
whatever. Avoid them whenever possible.
In particular don't use char for
arithmetic, the signedness problems with that are a plague. Use uint8_t or int8_t
if you feel the need for such a
thing.
Always initialize variables, all of them: integer, double, pointers, struct. It is
not true that this is less efficient
with a modern compiler. In most cases it will just
be optimized away when not necessary.
But especially pointer variables that
are not properly initialized can
produce spurious errors and make code
hard to debug. If you have them
initialized to NULL your program
will fail early, and your debugger will show you the place.
Compile with all warnings on, and
don't finish tidying your code until
the compiler doesn't give a single
warning. They are quite good at that nowadays, take advantage.
Compile with different optimization
options on, or even better with
different versions of your compiler,
or still better with completely
different compilers on different
platforms.
Use the assert macro. This forces you to think of your assumptions and also make your
code fail early if they are not fulfilled.
Unit testing. Makes getting your software correct a lot easier.
gdb is a debugger to analyse your program.
Other techinque is to use printf or logs
Valgrind provides dynamic analysis of the executable
Purify provides static and dynamic analysis. Sparrow and Prevent are some other tools in competition to Purify.
This can be separated into:
Prevention measures:
Use strict coding styles, don't make a mess
Use comments and code revisions
Use static code analysis tools
Use assertions where it's possible
Don't over complicate
Post-factum
Use debugger/tracer
Use memory checking tools
Use regression testing
Use your brain
Off the top of my head, Valgrind.
You might also want to hone your debugging skills by reading the book Debugging by David Agans. Every programmer should read this early on in their career.
valgrind for memory problems if you're on linux. use gdb/ddd on linux as well. On windows a lot of windows programmers don't seem to be knowledgeable of windbg. It is very useful but has a learning curve like gdb; more powerful than the built in debugger in visual studio. learn to use assert, you will catch lots of stuff and you can turn it off in release code if you so choose. Use a unit testing framework like Check, cunit, etc . Always initialize your pointer, to NULL if nothing else. When you free a pointer set it to NULL. Better you to catch a segfault than your user. Pick a coding standard and stick to it, consistency will help you make fewer mistakes. Keep your functions small if at all possible, this will keep you from having 10 level deep braces which are logic nightmares. If compiling using gcc use -Wall and -Wextra . Use the strn* functions instead of str* functions. Well worth the extra thinking they force you to do.

Resources