Author Topic: A reproducible crash of CC  (Read 24487 times)

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
A reproducible crash of CC
« on: August 07, 2011, 09:58:00 am »
Both under Linux or Windows, there is no way to find the cause.
Updated source code to the CB's HEAD, and then apply the patch.
Then opening any project CB will crash. :(

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #1 on: August 07, 2011, 10:31:21 am »
I think I find the reason: call TRACE in a sub thread is not allowed!
And this maybe the final reason of all the random crash!

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #2 on: August 07, 2011, 10:53:49 am »
I think we can't call: Manager::Get()->GetLogManager()->DebugLog(...) or Manager::Get()->GetLogManager()->Log(...) in any sub thread.
So, We need rewrite CC's Logger.
Any comments?

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5913
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: A reproducible crash of CC
« Reply #3 on: August 07, 2011, 11:43:23 am »
Good catch loaden!!!

looking at the code in include\logmanager.h

It seems the DebugLog function internally call:

Code
void LogInternal(const wxString& msg, int i, Logger::level lv) { if ((i>=0) && (i<=(int)max_logs) && (slot[i].log!=&g_null_log)) slot[i].log->Append(msg, lv); };

I can't find critical section or other resource locker there.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: A reproducible crash of CC
« Reply #4 on: August 07, 2011, 11:56:23 am »
Remember, the trace macro was actually only for debug purposes. I know, we mis-use it. :lol:

However, please don't mess with LogManager. That's not something to change. instead, we should always use events to report CC infos from threads to the plugin "main loop" itself. So instead of calling Log(...) directly, fire a custom event (implemented inside the CC plugin) and handle the call outside the thread.
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5913
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: A reproducible crash of CC
« Reply #5 on: August 07, 2011, 12:07:18 pm »
Remember, the trace macro was actually only for debug purposes. I know, we mis-use it. :lol:
Agree!!!
Quote
However, please don't mess with LogManager. That's not something to change. instead, we should always use events to report CC infos from threads to the plugin "main loop" itself. So instead of calling Log(...) directly, fire a custom event (implemented inside the CC plugin) and handle the call outside the thread.
Yes, correctly way we should use.
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #6 on: August 07, 2011, 12:53:04 pm »
we should always use events to report CC infos from threads to the plugin "main loop" itself.
Yes, this is what I called the CC's Logger.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #7 on: August 07, 2011, 11:09:37 pm »
Loaden: do you know that the singleton pattern is considered a bad pathern? Why are you doing CCLogger::Get(), instead of having m_logger or g_logger?

Some random links:
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
http://stackoverflow.com/questions/86654/whats-wrong-with-singleton
http://aabs.wordpress.com/2007/03/08/singleton-%E2%80%93-the-most-overused-pattern/

p.s. I don't like the Manager::Get() thing, too :P
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #8 on: August 08, 2011, 01:56:04 am »
Loaden: do you know that the singleton pattern is considered a bad pathern? Why are you doing CCLogger::Get(), instead of having m_logger or g_logger?

Some random links:
http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx
http://stackoverflow.com/questions/86654/whats-wrong-with-singleton
http://aabs.wordpress.com/2007/03/08/singleton-%E2%80%93-the-most-overused-pattern/

p.s. I don't like the Manager::Get() thing, too :P
Singleton pattern in here, nothing bad.
I do not like global variables.
In here, we can't use member variables, It will be worse.

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #9 on: August 08, 2011, 02:14:46 am »
Singleton is a global variable!!! They call it glorified global variable.
What do you gain by using singleton in this case? Instead of global variable or global variable hidden behind two functions cc::DebugLog and cc::Log (and of course one init function)?

BTW: Your Get() method is not thread safe:)

Also don't use double locking if you try to make it thread safe:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://bartoszmilewski.wordpress.com/2008/08/04/multicores-and-publication-safety/
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #10 on: August 08, 2011, 05:41:11 am »
Singleton is a global variable!!! They call it glorified global variable.
What do you gain by using singleton in this case? Instead of global variable or global variable hidden behind two functions cc::DebugLog and cc::Log (and of course one init function)?

BTW: Your Get() method is not thread safe:)

Also don't use double locking if you try to make it thread safe:
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
http://bartoszmilewski.wordpress.com/2008/08/04/multicores-and-publication-safety/
In this case, we not need thread-safe for CCLogger::Get.
CCLogger::Get should call first in CodeCompletion::CodeCompletion():
Code
CodeCompletion::CodeCompletion() :
...
{
    CCLogger::Get()->Init(this, idCCLogger, idCCDebugLogger);

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 5913
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: A reproducible crash of CC
« Reply #11 on: August 08, 2011, 05:43:54 am »
Also don't use double locking if you try to make it thread safe:
Which code use double locking? Can you give a direction in the CC's code(trunk HEAD)?
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline Loaden

  • Lives here!
  • ****
  • Posts: 1014
Re: A reproducible crash of CC
« Reply #12 on: August 08, 2011, 05:59:43 am »
Also don't use double locking if you try to make it thread safe:
Which code use double locking? Can you give a direction in the CC's code(trunk HEAD)?
if you try to make it thread safe:
 :lol:

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #13 on: August 08, 2011, 09:28:58 am »
In this case, we not need thread-safe for CCLogger::Get.
CCLogger::Get should call first in CodeCompletion::CodeCompletion():
So you're admitting that you're using this singleton as glorified global variable? :)
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: A reproducible crash of CC
« Reply #14 on: August 08, 2011, 11:08:42 am »
Seeing how I'm the guy who wrote that apparently incomprehensible code, here's an explanation of how this was conceived:

  • Logging uses a singleton, yes. There is no issue with that, it does not need locks. Making singletons threadsafe is a stupid, useless endeavor, because it does not work. It isn't an issue either, because the LogManager has been initialized ages before the CC plugin is ever loaded. After that, it is no more than a forwarded pointer.
  • If you call DebugLog, this gets redirected (via 2 layers, if I remember correctly) to the concrete Logger object that is currently plugged in the debug_log slot. This enables, in theory, the application to for example start up in "no log" mode in case Code::Blocks runs in absence of GUI or even in absence of a terminal, or it allows a hypothetical Code::Blocks to send you e-mails for log messages.
  • Loggers have exactly two requirements: They must implement the pure virtual Append function, and they must work in presence and absence of GUI and in presence or absence of several threads without crashing. Whatever, they must work without crashing.
  • Loggerss are explicitly not required to do validation, or to produce meaningful or correct output or any output at all. It is perfectly acceptable for a Logger to output something ill-formatted or nothing at all, as long as it does not crash. If you fill shit into a logger, it's perfectly good if shit comes out of it.
  • The reasoning behind the above was that there was the long-existent wish to make a commandline version of Code::Blocks which was impossible because every darn tiny function in the entire program called a log macro which required a GUI, just to output a text that nobody wanted to read, and there was no way to turn this off.
  • TextCtrlLogger and his brethren, which are the ones used by default do not use a critical section, that is correct. This means that there is a race condition between control->SetDefaultStyle and control->AppendText. Thus, if an "error" and an "info" are logged concurrently, it is possible that the info is colored as an error or the other way around.
    At the time of writing the class, I considered that since nobody would probably want to write thousands of log messages concurrently from half a dozen threads, this was unnecessary overhead, since the worst thing to happen would be wrongly colored messages, which I deemed a "so what" issue.
  • There is no other reason (i.e. crash) which is obvious to me why you could not log concurrently. Unless wxWidgets GUI functions are not re-entrant, which I would seriously hope they are.
  • There is, however, also no reason not to insert a critical section inside TextCtrlLogger::Append either, if you believe that this fixes a crash.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: A reproducible crash of CC
« Reply #15 on: August 08, 2011, 11:14:59 am »
In this case, we not need thread-safe for CCLogger::Get.
CCLogger::Get should call first in CodeCompletion::CodeCompletion():
So you're admitting that you're using this singleton as glorified global variable? :)
That's exactly how the entire project is organized, every "...Manager" class, whether it's configuration, project, buildtargets or whatever.

You can debate whether that's bad design or not, whether singletons are better or worse or the same as global variables, but that's what it is, really. Someone (most probably Yiannis?) started it that way, and everyone (including me) continued that way. The fact that we use singletons everywhere didn't cause a lot of trouble during the years either. Yes, we won't win the first prize in the OOP design contest, so what. The point is, it works, and it works in a kind-of-defined way.

In at least one case (config) there is an urgent reason behind it too, in most other cases I guess one cold probably do otherwise, if one cares to spend many hours rewriting a lot of code.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #16 on: August 08, 2011, 12:42:53 pm »
  • There is no other reason (i.e. crash) which is obvious to me why you could not log concurrently. Unless wxWidgets GUI functions are not re-entrant, which I would seriously hope they are.
They are not, all GUI libs I've seen (MFC/Win32api, QT, wxWidgets) are intended for single threaded usage.

In at least one case (config) there is an urgent reason behind it too, in most other cases I guess one cold probably do otherwise, if one cares to spend many hours rewriting a lot of code.
I've not said to rewrite all existing code. I know it is impossible.
I just want to not make the same mistake with the new code.
This CCLogger::Get()->BlaBla() is more typing, more instructions and more memory accesses for no added benefit/value.
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: A reproducible crash of CC
« Reply #17 on: August 11, 2011, 11:59:25 am »
Did you try whether a critical section in TextCtrlLogger::Append does anything?

I don't believe this makes any difference, but you never know if you haven't tried...
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #18 on: August 11, 2011, 12:30:04 pm »
I haven't, the better approach is to send/post a message/event, this will be even asynchronous :)
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: A reproducible crash of CC
« Reply #19 on: August 11, 2011, 03:26:22 pm »
Yep, we could send log messages via a TCP socket.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline oBFusCATed

  • Developer
  • Lives here!
  • *****
  • Posts: 13413
    • Travis build status
Re: A reproducible crash of CC
« Reply #20 on: August 11, 2011, 03:46:12 pm »
Hm, probably you forget the smiley in the previous post? :)
(most of the time I ignore long posts)
[strangers don't send me private messages, I'll ignore them; post a topic in the forum, but first read the rules!]