ug4
Loading...
Searching...
No Matches
Debugging UG4's C/C++ Code

"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

cmake -DDEBUG_LOGS=ON ..

(otherwise all UG_DLOG/IF_DEBUGs will be ignored).

It works like this: In your LUA-Script, you add the line

set_debug(debugID.MAIN, 2)

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: GetLogAssistant():set_debug_level("MAIN", 2) Internally, it is debugID.MAIN = "MAIN".

Now the debug level for the 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:

UG_LOG("Hello World " << myInteger << "\n");
#define UG_LOG(msg)
Definition log.h:367

If you want a message to be printed only if the DebugID MAIN is 2, you do

UG_DLOG(MAIN, 2, "my debug message");
#define UG_DLOG(__debugID__, level, msg)
Definition log.h:298

There's also a way to control if a block is exectuted or not:

IF_DEBUG(MAIN, 3)
{
// do sth.
}
#define IF_DEBUG(__debugID__, level)
Definition log.h:303

By default, UG4 has the following DebugIDs:

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

For a complete list, use

print(GetLogAssistant():get_debug_IDs())
function table print(data, style)

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

#include "common/log.h"
DebugID DID_MYAPP("MYAPP");

Now you can use it in any C++ file this way

#include "common/log.h"
extern DebugID DID_MYAPP;
void myFunction()
{
UG_DLOG(DID_MYAPP, 1, "my msg");
}

and set the debug level in lua

set_debug(debugID.MYAPP, 1)

Alternatively GetLogAssistant():set_debug_level("MYAPP", 1).

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

#include "common/log.h"
DebugID DID_MYAPP_FUNC1("MYAPP.FUNC1");
DebugID DID_MYAPP_FUNC2("MYAPP.FUNC2");

Now you can do

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
See also
ug::LogAssistant, UG_LOG, UG_DLOG

Debugging UG4 with gdb

To debug ug4, you have to make

cmake -DDEBUG=ON ..

Note GCC 4.1.2 .

Then you do

gdb ugshell
b myfile.cpp:33
run -ex myscript.lua -myParameter1 3.4 -myOption2

Another possibility is use –args

gdb --args ugshell -ex myscript.lua -myParameter1 3.4 -myOption2
b myfile.cpp:33
run

For simple parallel debugging, see xprun .

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:

  1. compile ug4 static: cmake -DSTATIC_BUILD=ON ..
  2. adding the breakpoints "pending". you can use set breakpoint pending on to avoid the y/n. Note that now gdb won't tell you if your filename was wrong.
  3. we've added a function SharedLibrariesLoaded . You can set a breakpoint there with b SharedLibrariesLoaded. After that, you'll be able to break in your plugin/ug4.

Best way is to create a .gdbinit file in your ug4/bin directory like this:

b SharedLibrariesLoaded
run

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

Then you can start your code with

gdb --args ugshell -ex myscript.lua -myParameter1 3.4 -myOption2

and it will break right after all shared libraries have been loaded. Now you can add your breakpoints.

Note
You will need to cont after that, NOT run.

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

Debugging LUA and C++

You can debug your LUA code with the tools here: Debug Shell.

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

void breakpoint()
Definition lua_debug.cpp:203

This gives you the possibility to check LUA variables and the LUA execution position when your C++ code crashed.

Note
You have to enter cont to get back to gdb, not quit.

If you only need the current LUA execution position, use

(gdb) call ug::bridge::ScriptStacktrace()