ug4
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
DebugID MAIN

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

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

By default, UG4 has the following DebugIDs:

DebugID LIB_DISC
Definition: debug_id.h:117
DebugID LIB_GRID_REFINER
Definition: debug_id.h:116
DebugID LIB_DISC_NEWTON
Definition: debug_id.h:121
DebugID LIB_DISC_LINKER
Definition: debug_id.h:122
DebugID LIB_ALG_LINEAR_SOLVER
Definition: debug_id.h:128
DebugID APP
Definition: debug_id.h:114
DebugID LIB_DISC_OPERATOR_INVERSE
Definition: debug_id.h:126
DebugID LIB_ALG_VECTOR
Definition: debug_id.h:129
DebugID LIB_DISC_ASSEMBLE
Definition: debug_id.h:118
DebugID LIB_ALG_LINEAR_OPERATOR
Definition: debug_id.h:127
DebugID LIB_ALG_MATRIX
Definition: debug_id.h:130
DebugID LIB_DISC_OUTPUT
Definition: debug_id.h:125
DebugID LIB_ALG_AMG
Definition: debug_id.h:131
DebugID LIB_DISC_D3F
Definition: debug_id.h:119
DebugID LIB_DISC_DISCRETE_FUNCTION
Definition: debug_id.h:124
DebugID LIB_GRID
Definition: debug_id.h:115
DebugID LIB_PCL
Definition: debug_id.h:132
DebugID LIB_DISC_MULTIGRID
Definition: debug_id.h:120

For a complete list, use

print(GetLogAssistant():get_debug_IDs())
function table print(data, style)
LogAssistant & GetLogAssistant()
Definition: log_impl.h:69

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