/*
 * Copyright (c) 2012-2015:  G-CSC, Goethe University Frankfurt
 * Author: Martin Rupp
 * 
 * This file is part of UG4.
 * 
 * UG4 is free software: you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License version 3 (as published by the
 * Free Software Foundation) with the following additional attribution
 * requirements (according to LGPL/GPL v3 §7):
 * 
 * (1) The following notice must be displayed in the Appropriate Legal Notices
 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
 * 
 * (2) The following notice must be displayed at a prominent place in the
 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
 * 
 * (3) The following bibliography is recommended for citation and must be
 * preserved in all covered files:
 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
 *   parallel geometric multigrid solver on hierarchically distributed grids.
 *   Computing and visualization in science 16, 4 (2013), 151-164"
 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
 *   flexible software system for simulating pde based models on high performance
 *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 */

/** \page pageDebuggingCPP Debugging UG4's C/C++ Code

[TOC]

\section secDebuggingOutput "printf" debugging UG4

We incorporated a logging mechanism into UG4 to faciliate printing messages 
for test purposes. To enable it, you need to make ug with
\verbatim
cmake -DDEBUG_LOGS=ON ..
\endverbatim
(otherwise all UG_DLOG/IF_DEBUGs will be ignored).

It works like this: In your LUA-Script, you add the line
\code
set_debug(debugID.MAIN, 2)
\endcode

Note that the debugID structure is supported by the UGIDE code completion so you are more aware of which debugIDs exist or not.

Alternatively, you can use the old version of this: <tt> GetLogAssistant():set_debug_level("MAIN", 2)</tt>
Internally, it is <tt>debugID.MAIN = "MAIN"</tt>.

Now the debug level for the \em DebugID MAIN is set to 2. Now in the C++ code,
you can do logging with UG_LOG, using some ostream functionality like in cout:
\code
UG_LOG("Hello World " << myInteger << "\n");
\endcode
If you want a message to be printed only if the DebugID MAIN is 2, you do
\code
UG_DLOG(MAIN, 2, "my debug message");
\endcode
There's also a way to control if a block is exectuted or not:
\code
IF_DEBUG(MAIN, 3)
{
    // do sth.
}
\endcode
By default, UG4 has the following DebugIDs:
\code
MAIN, APP, LIB_GRID, LIB_GRID_REFINER, LIB_DISC, LIB_DISC_ASSEMBLE, LIB_DISC_D3F,
LIB_DISC_MULTIGRID, LIB_DISC_NEWTON, LIB_DISC_LINKER, LIB_DISC_TRANSER, LIB_DISC_DISCRETE_FUNCTION,
LIB_DISC_OUTPUT, LIB_DISC_OPERATOR_INVERSE, LIB_ALG_LINEAR_OPERATOR, LIB_ALG_LINEAR_SOLVER,
LIB_ALG_VECTOR, LIB_ALG_MATRIX, LIB_ALG_AMG, LIB_PCL
\endcode
For a complete list, use
\code
print(GetLogAssistant():get_debug_IDs())
\endcode
in your script. You can also add custom debug IDs in the following way: You need to create one
global object of the class DebugID (in a cpp-file):
\code
#include "common/log.h"
DebugID DID_MYAPP("MYAPP");
\endcode
Now you can use it in any C++ file this way
\code
#include "common/log.h"
extern DebugID DID_MYAPP;
void myFunction()
{
    UG_DLOG(DID_MYAPP, 1, "my msg");
}
\endcode
and set the debug level in lua
\code
set_debug(debugID.MYAPP, 1)
\endcode

Alternatively <tt>GetLogAssistant():set_debug_level("MYAPP", 1)</tt>.

Note the difference between the DebugID object DID_MYAPP and its associated string "MYAPP" - you can use for both the same, 
of course.

You can also subdivide Debug IDs: Say you have an app called "MYAPP" and some subfunctions "FUNC1" and "FUNC2". Then 

\code
#include "common/log.h"
DebugID DID_MYAPP_FUNC1("MYAPP.FUNC1");
DebugID DID_MYAPP_FUNC2("MYAPP.FUNC2");
\endcode
Now you can do
\code
set_debug(debugID.MYAPP, 2)  --- sets debug level of MYAPP.FUNC1 and MYAPP.FUNC1 to 2
set_debug(debugID.MYAPP.FUNC1, 1)  --- sets MYAPP.FUNC1 to 1
\endcode




\sa ug::LogAssistant, UG_LOG, UG_DLOG

\section secDebuggingUG4CPP Debugging UG4 with gdb
To debug ug4, you have to make
\verbatim
cmake -DDEBUG=ON ..
\endverbatim
Note \ref secCMake_GCC412 .

Then you do 
\verbatim
gdb ugshell
b myfile.cpp:33
run -ex myscript.lua -myParameter1 3.4 -myOption2
\endverbatim

Another possibility is use <tt>--args</tt>
\verbatim
gdb --args ugshell -ex myscript.lua -myParameter1 3.4 -myOption2
b myfile.cpp:33
run
\endverbatim
For simple parallel debugging, see \ref bashToolsXprun .

\section secDebuggingCPPTroubleshooting Debug Troubleshooting
Sometimes you cannot set breakpoints because the source is in a shared library. This is true for all plugins. 
Also ug4 is loaded dynamically from ugshell. There are two solutions for this:
<ol>
<li> compile ug4 static: <tt>cmake -DSTATIC_BUILD=ON ..</tt>
<li> adding the breakpoints "pending". you can use <tt>set breakpoint pending on</tt> to avoid the y/n. Note that now gdb won't 
tell you if your filename was wrong.
<li> we've added a function SharedLibrariesLoaded . You can set a breakpoint there with <tt>b SharedLibrariesLoaded</tt>. After that,
you'll be able to break in your plugin/ug4.
</ol>

Best way is to create a <tt>.gdbinit</tt> file in your ug4/bin directory like this:
\verbatim
b SharedLibrariesLoaded
run

echo shared libraries now loaded.\n
# add your breakpoints after this line
# cont
\endverbatim

Then you can start your code with
\verbatim
gdb --args ugshell -ex myscript.lua -myParameter1 3.4 -myOption2
\endverbatim

and it will break right after all shared libraries have been loaded. Now you can add your breakpoints.
\note You will need to <tt>cont</tt> after that, NOT <tt>run</tt>.

You can also add your breakpoints in the .gdbinit file and a <tt>cont</tt> at the end. That way you'll have to type less.

\section secDebuggingLUA Debugging LUA and C++

You can debug your LUA code with the tools here: \ref secDebugging.

\warning Keep in mind that the LUA/ugshell debugger is a completely different thing as the GDB debugger!

You can access the LUA debugger within GDB by writing in the gdb shell
\code
(gdb) call ug::script::breakpoint()
\endcode

This gives you the possibility to check LUA variables and the LUA execution position when your C++ code crashed.
\note You have to enter <tt>cont</tt> to get back to gdb, \em not quit.

If you only need the current LUA execution position, use
\code
(gdb) call ug::bridge::ScriptStacktrace()
\endcode


*/
