I'm currently programming an SDL Network Game, everything is perfect ... But my game only runs at 30fps, so I ran a Very Sleepy analysis.
First strange effect, very sleepy increase the perfs of my Game to 60Fps ... ( Why ? )
And secondly, there is a lot of SDL_LogCritical calls ( you can get the report here : http://puu.sh/gauEi/9a852462e6.png ). And nothing is shown in the console.
( I also use SDLNet, with TCP protocol, there is no packet loose ).
Moreover, I overwritten the output for SDL Logs :
void log(void* userdata, int category, SDL_LogPriority priority, const char* message) {
std::cout << "Log : " << message << std::endl;
}
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_EVERYTHING);
SDLNet_Init();
SDL_LogSetOutputFunction(log, NULL);
SDL_LogCritical(1, "TEST LOG");
}
And I can see the "TEST LOG" in the console. So the SDL_LogCritical which consumme 30% doesn't output everything .
I don't know what's wrong, but frequent calls to a logging function indicate that something is wrong and SDL tries to tell you about it. However, the lack of output might be caused by you explicitely or implicitely disable logging to the console. Your use of Network might indicate your not looking at the right console to see these warnings. It's all a bit hard to diagnose with the lack of information given.
Performance increase due to debugging is strange, but can often be explained by the fact that the debugger doesn't use exactly the same environment as you do when running normally.
OK, so you're not seeing output when something else calls SDL's log functionality. This points to the messages being logged somehow being below necessary priority. Compare SDL's source code to find out how that could be happening. Maybe you should, at this point, use a debugger to set breakpoints.
Related
I am making a small system and I want to be able to toggle "verbose" text output in the whole system.
I have made a file called globals.h:
namespace REBr{
extern bool console_verbose = false;
}
If this is true I want all my classes to print a message to the console when they are constructing, destructing, copying or doing pretty much anything.
For example:
window(string title="",int width=1280,int height=720):
Width(width),Height(height),title(title)
{
if(console_verbose){
std::cout<<"Generating window #"<<this->instanceCounter;
std::cout<<"-";
}
this->window=SDL_CreateWindow(title.c_str(),0,0,width,height,SDL_WINDOW_OPENGL);
if(console_verbose)
std::cout<<"-";
if(this->window)
{
this->glcontext = SDL_GL_CreateContext(window);
if(console_verbose)
std::cout<<".";
if(this->glcontext==NULL)
{
std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_OPENGLCONTEXT: "<<SDL_GetError()<<std::endl;
}
}
else std::cout<<"FATAL ERROR IN REBr::WINDOW::CONSTR_WINDOW: "<<SDL_GetError()<<std::endl;
if(console_verbose)
std::cout<<">done!"<<endl;
}
Now as you can see I have a lot of ifs in that constructor. And I REALLY dont want that since that will slow down my application. I need this to be as fast as possible without removing the "loading bar" (this helps me determine at which function the program stopped functioning).
What is the best/fastest way to accomplish this?
Everying in my system is under the namespace REBr
Some variants to achieve that:
Use some logger library. It is the best option as it gives you maximum flexibility and some useful experience ;) And you haven't to devise something. For example, look at Google GLOG.
Define some macro, allowing you to turn on/off all these logs by changing only the macro. But it isn't so easy to write such marco correctly.
Mark your conditional flag as constexpr. That way you may switch the flag and, depending on its value, compiler will optimise ifs in compiled program. But ifs will still be in code, so it looks kinda bulky.
Anyway, all these options require program recompilation. W/o recompilation it is impossible to achieve the maximum speed.
I often use a Logger class that supports debug levels. A call might look like:
logger->Log(debugLevel, "%s %s %d %d", timestamp, msg, value1, value2);
The Logger class supports multiple debug levels so that I can fine tune the debug output. This can be set at any time through the command line or with a debugger. The Log statement uses a variable length argument list much like printf.
Google's logging module is widely used in the industry and supports logging levels that you can set from the command line. For example (taken from their documentation)
VLOG(1) << "I'm printed when you run the program with --v=1 or higher";
VLOG(2) << "I'm printed when you run the program with --v=2 or higher";
You can find the code here https://github.com/google/glog and the documentation in the doc/ folder.
It's just plain luck my program is so simple, so I eventually found out what causes the mysterious log message. My program log looks like this:
Debugging starts
failed to start
Debugging has finished
Which happens after:
camera = new QCamera(QCameraInfo::defaultCamera());
// see http://omg-it.works/how-to-grab-video-frames-directly-from-qcamera/
camera->setViewfinder(frameGrabber = new CameraFrameGrabber());
camera->start();
The start() method causes this message in console. Now the meaning of the message is obvious, what it's not very helpful. What steps should I take to troubleshoot it?
Reasons for this might differ, but in my case it was simply because I provided invalid QCameraInfo. The culprit is that QCameraInfo::defaultCamera() might return invalid value if Qt fails to detect any cameras on your system, which unfortunately happens even if cameras are present.
So if I write the following code:
MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);
the program crashes with an access violation when it exits. When I write the code like this:
int a;
a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);
it doesn't crash. Now I know why it crashes when it crashes thanks to another question I asked, also regarding argument-mismatching, but I don't know why it crashes.
So why does this cause an APPCRASH? I was always under the impression that calling a function that had a return-type, without actually giving one was safe, example:
int SomeFunction (void) {
std::cout << "Hello ya'll!\n";
return 42;
}
int main (void) {
int a;
// "Correct" ?
a = SomeFunction();
a = MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);
// "Incorrect" ?
SomeFunction();
MessageBoxA(0, "Yo, wazzup!", "A Greeting From Earth", 0);
}
When I run this kind of test "clean" (in a new file) I don't get any errors. It only seems to give an error with MessageBox/MessageBoxA when run in my program. Knowing the possible causes would help me pinpoint the error as the project code is too big to post (and I would need my friend's permission to post his code anyway).
Additional Info:Compiler = GCCPlatform = Windows
EDIT:
UpdateThanks everyone for your feedback so far. So I decided to run it through a debugger... Now Code::Blocks doesn't debug a project unless it is loaded from a project file (*.cbp) - AFAIK. So I created an actual project and copy-pasted our project's main file into the projects. Then I ran in debug mode and didn't get so much as a warning. I then compiled in build mode and it ran fine.Next, I decided to open a new file in Dev-C++ and run it through the debugging and later the final build process and again I got no errors for either build or debug. I cannot reproduce this error in Dev-C++, even with our main file (as in the one that causes the error in Code::Blocks).
ConclusionThe fault must lie in Code::Blocks. AFAIK, they both use GCC so I am pretty confused. The only thing I can think of is a version difference or perhaps my compiler settings or something equally obscure. Could optimizer settings or any other compiler settings somehow cause this kind of error?
The version with the return value does not crash because it had one int more on the stack. Your erroneous code reads over the bounds of the stack and then runs into an access violation. But if you have more on the stack you will not hit the guard page, because that is just enough extra stack. If the the erroneous code only reads it is sort of OK, but still broken.
We had one bit of WTF inducing code that was like so:
char dummy[52];
some_function();
There was thankfully a longish comment explaining that removing dummy, makes some_function crash. It was in a very old application so nobody dared touch it and the some_function was totally different module we had no control over. Oh yea and that application was running smoothly in the field for over 20 years in industrial installations, like refineries or nuclear power plants... ^_^
I have a "black box" question about an error I get when I run a discrete event simulation for about a minute. Everything works fine, and it completes successfully, but the system prints the following message once at some point during the simulation:
Error (202): Command token too long
I've never seen anything like it. I wonder what "command" it's referring to. Perhaps it's system("...") call that I make several times in the program in order to plot and visualize the data it generates.
I'm sorry I can't provide any code as I'm not sure where the error is coming from. Is there an efficient way to discover at which point the system generates this message? Or in any case, have you encountered such an error in your own C++ programming experience, and thus suggest where it could possibly be coming from?
I'm using Ubuntu 11.04 and compiling with GCC. The error appears at run-time during the simulation for simulations that are especially long (30+ seconds), and doesn't appear in shorter cases. I should emphasize that the "error" doesn't stop the execution of the code and doesn't actually cause any visible errors in the visual output of the simulation data.
write a program similar to the following:
int trials 10000;
string str("ls ");
while( trials--)
{
system( str.c_str() );
str += "a";
cout << "chars in cmd = " << trials << endl;
}
It will successively run commands like
ls, ls a, ls aa, ls aaa, while simultaneously printing to the console what trial # it's on.
and if you're right about where the error is coming from, eventually it will get the same error message about "token too long", and if so, tell you how many characters the cmd may be. Then code this limit into your real C++ program so that it doesn't emit the error.
If it doesn't reproduce the error, try making # trials bigger, say up to 100k. If it still doesn't happen, the error is probably coming from somewhere else.
It's coming from a lexer, telling you that one of the tokens (identifiers/preproc tokens/etc.) in your program is rather lengthy. Look through your code to see if there are any ridiculously long strings or preprocessor tokens.
I want to program a daemon-manager that takes care that all daemons are running, like so (simplified pseudocode):
void watchMe(filename)
{
while (true)
{
system(filename); //freezes as long as filename runs
//oh, filename must be crashed. Nevermind, will be restarted
}
}
int main()
{
_beginThread(watchMe, "foo.exe");
_beginThread(watchMe, "bar.exe");
}
This part is already working - but now I am facing the problem that when an observed application - say foo.exe - crashes, the corresponding system-call freezes until I confirm this beautiful message box:
This makes the daemon useless.
What I think might be a solution is to make the main() of the observed programs (which I control) "uncrashable" so they are shutting down gracefully without showing this ugly message box.
Like so:
try
{
char *p = NULL;
*p = 123; //nice null pointer exception
}
catch (...)
{
cout << "Caught Exception. Terminating gracefully" << endl;
return 0;
}
But this doesn't work as it still produces this error message:
("Untreated exception ... Write access violation ...")
I've tried SetUnhandledExceptionFilter and all other stuff, but without effect.
Any help would be highly appreciated.
Greets
This seems more like a SEH exception than a C++ exception, and needs to be handled differently, try the following code:
__try
{
char *p = NULL;
*p = 123; //nice null pointer exception
}
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
cout << "Caught Exception. Terminating gracefully" << endl;
return 0;
}
But thats a remedy and not a cure, you might have better luck running the processes within a sandbox.
You can change the /EHsc to /EHa flag in your compiler command line (Properties/ C/C++ / Code Generation/ Enable C++ exceptions).
See this for a similar question on SO.
You can run the watched process a-synchronously, and use kernel objects to communicate with it. For instance, you can:
Create a named event.
Start the target process.
Wait on the created event
In the target process, when the crash is encountered, open the named event, and set it.
This way, your monitor will continue to run as soon as the crash is encountered in the watched process, even if the watched process has not ended yet.
BTW, you might be able to control the appearance of the first error message using drwtsn32 (or whatever is used in Win7), and I'm not sure, but the second error message might only appear in debug builds. Building in release mode might make it easier for you, though the most important thing, IMHO, is solving the cause of the crashes in the first place - which will be easier in debug builds.
I did this a long time ago (in the 90s, on NT4). I don't expect the principles to have changed.
The basic approach is once you have started the process to inject a DLL that duplicates the functionality of UnhandledExceptionFilter() from KERNEL32.DLL. Rummaging around my old code, I see that I patched GetProcAddress, LoadLibraryA, LoadLibraryW, LoadLibraryExA, LoadLibraryExW and UnhandledExceptionFilter.
The hooking of the LoadLibrary* functions dealt with making sure the patching was present for all modules. The revised GetProcAddress had provide addresses of the patched versions of the functions rather than the KERNEL32.DLL versions.
And, of course, the UnhandledExceptionFilter() replacement does what you want. For example, start a just in time debugger to take a process dump (core dumps are implemented in user mode on NT and successors) and then kill the process.
My implementation had the patched functions implemented with __declspec(naked), and dealt with all the registered by hand because the compiler can destroy the contents of some registers that callers from assembly might not expect to be destroyed.
Of course there was a bunch more detail, but that is the essential outline.