Need trace of user methods called when running Qt Creator 2.6.0 based on Qt 4.8.2 with g++ 4.4.7 or MS Visual Studio 2010

Using Qt Creator 2.6.0 based on Qt 4.8.2 with g++ 4.4.7 or MS Visual Studio 2010.

Was given project consisting of dozens of classes each containing many methods.

I do not want to put in break points in every method to find out which methods are called - too many methods.  Is there any way to get the QT compiled code to generate a log of the methods called while running the program?

Note that updating programs or compiler is not allowed so I am stuck with what I have.
LVL 33
phoffricAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sarabandeCommented:
imo there is no log of the current stack.

to show call hierarchy into the output window of the IDE you might add

qDebug() << "begin " << __FUNCTION__ << "\n";

at begin of each function

and

qDebug() << "end " << __FUNCTION__ << "\n";

at each return.

this can easily made more comfortable by defining macros.

#define BEG_FUNC qDebug() << "begin " << __FUNCTION__ << "\n";

in a global header file. it is also possible to indent the function names properly if you want.

note the qDebug() would do nothing in release build. so you could use the macros both in debug or release.

Sara
0
phoffricAuthor Commented:
In some previous projects, I've done those ENTER/EXIT messages before for specific functions. But I am looking for a trace of functions for the entire program as they are called without having to modify any code. I just hit the green Debug run button, and hope to get a trace.

Hopefully, there is a way to do this by setting up some compiler configuration.
0
phoffricAuthor Commented:
Keep in mind that I would rather not do the code modification that you suggest for 1000+ methods. I would not be allowed to include that in my code base, so in the end, I would have to remove them. I am just trying to navigate my way around 22K+ LOCs.
0
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

phoffricAuthor Commented:
<<EDIT>>
I have updated the question with the correct version numbers:
Qt Creator 2.6.0 based on Qt 4.8.2 with g++ 4.4.7.
0
sarabandeCommented:
i recently worked in huge project with millions of lines of code. we used macros at the begin and end of functions (non-trivial functions only) in order to get a trace and to implement a try-catch for each function. this was done over decades but adding those macros for new code is no efforts. actually it is also not very difficult to write a little tool which adds those macros to existing code. of course you might need a few of  persuading what might be easier if you can show a sample project where it already worked and where the advantages can be seen.

Sara
0
phoffricAuthor Commented:
I recall in the past that I was able to get a function trace without having to modify the code base. I just started a new job and do not want to persuade the lead to do this.

I am looking for a qt creator method to do this without having to change the code.
0
Duncan RoeSoftware DeveloperCommented:
With the constraints you face, you have to go for gdb breakpoints: there is no other way.
Given your assignment, I would go for a specialised expect script to drive gdb, using as a start point my generalised gdb expect script "ggo". ggo feeds gdb breakpoint and other commands from its command line, but would not be appropriate for literally thousands of breakpoints. The specialised script would set the breakpoints from a list of functions that you'll have to come up with. On hitting a breakpoint, the script reports the function being entered and sends gdb a fin command. On hitting a fin termintaion, the script reports the function being returned from and issues another fin command.

HTH
1
joinaunionCommented:
Have you tried using Qt debug mode? Or is this not a option for you?
http://doc.qt.io/qtcreator/creator-debug-mode.html
1
phoffricAuthor Commented:
>>  you have to go for gdb breakpoints: there is no other way.
Ok, you are saying that "it cannot be done". I will try to find a mechanism to do this without modifying the existing code or using breakpoints. I think I found a Linux lead yesterday, but will need to find some time next week to see if it does the job. (I cannot always get on a Linux workstation - have to borrow one when the owner has logged out for the day.)

>>Have you tried using Qt debug mode? Or is this not a option for you?
I am guessing that you are suggesting that I put in breakpoints in the hundreds of methods.

From the OP:
I do not want to put in break points in every method to find out which methods are called - too many methods.
0
phoffricAuthor Commented:
BTW, I thought I saw that gdb allows regex in setting breakpoints, so that if all the methods began with XYZ, then I could set a breakpoint on all the methods beginning with XYZ in one command. That would have been half way acceptable. At least I could keep hitting "go" and get a list that way. Ideally, with breakpoints, I would want a "continue" in the action on hitting the breakpoint so that I wouldn't have to keep going manually.

But the legacy project that I am looking at does not have any universal pattern in naming methods.
0
joinaunionCommented:
It may be possible to use the built in debugging helpers they have 200 or more built in.
Qt Creator ships with debugging helpers for more than 200 of the most popular Qt classes, standard C++ containers, and smart pointers, covering the usual needs of a C++ application developer out-of-the-box.
http://doc.qt.io/qtcreator/creator-debugging-helpers.html
0
phoffricAuthor Commented:
If you could be more specific in using debugging helpers as to how to solve my question, i would appreciate that.

I am not interested in examining Qt classes or standard C++ container, or smart pointers usage. The only thing I am interested in is seeing what programmer defined methods are called when I start the program and let it run for a few seconds. Right now, it is hard for me to know what are is being called and the order they are called in once the GUI is displayed.

There are 1000's of Qt SIGNALS and SLOTS connections, so a manual trace is very difficult for the 1000 methods.
0
phoffricAuthor Commented:
>> imo there is no log of the current stack.
Not absolutely positive of what you are referring to, but if you are saying that "the OP goal can't be done", then I have found a way to accomplish this goal.

>> qDebug() << "begin " << __FUNCTION__ << "\n";  at begin of each function
Violates the terms of the OP:
      "Note that updating programs or compiler is not allowed"
   
>> you have to go for gdb breakpoints: there is no other way.
>> Have you tried using Qt debug mode?
Violates the terms of the OP:
      "I do not want to put in break points in every method to find out which methods are called - too many methods."
0
phoffricAuthor Commented:
Here is how to solve the OP question for Linux.

When compiling the modules to get a trace of the Enter/Exit calling sequence, add the compiler option:
-finstrument-functions
Here is the documentation for this option:

Generate instrumentation calls for entry and exit to functions. Just after function entry and just before function exit, the following profiling functions are called with the address of the current function and its call site. (On some platforms, __builtin_return_address does not work beyond the current function, so the call site information may not be available to the profiling functions otherwise.)

void __cyg_profile_func_enter (void *this_fn,   void *call_site);
void __cyg_profile_func_exit  (void *this_fn,     void *call_site);

The first argument is the address of the start of the current function, which may be looked up exactly in the symbol table. I didn't figure out what the call_site address was from the output, so I just didn't print it out. For these two functions, I had to use the following to get the C code to mix in properly with the C++ code:
extern "C"
{
... // the implementation of the enter/exit functions.
}

Open in new window


This instrumentation is also done for functions expanded inline in other functions. The profiling calls indicate where, conceptually, the inline function is entered and exited. This means that addressable versions of such functions must be available. If all your uses of a function are expanded inline, this may mean an additional expansion of code size. If you use extern inline in your C code, an addressable version of such functions must be provided. (This is normally the case anyway, but if you get lucky and the optimizer always expands the functions inline, you might have gotten away without providing static copies.)

A function may be given the attribute no_instrument_function, in which case this instrumentation is not done. This can be used, for example, for the profiling functions listed above, high-priority interrupt routines, and any functions from which the profiling functions cannot safely be called (perhaps signal handlers, if the profiling routines generate output or allocate memory).
https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html

By writing your own customized functions:
__cyg_profile_func_enter
__cyg_profile_func_exit

Open in new window

you can get the calling sequence.  You can even add proper indentation to make the nesting calling sequence easier to read. This results in the addresses of the functions/methods being called - not too user-friendly.

Next step is to run nm --demangle on the executable.

This provides a nice mapping of addresses to the functions/methods. (Actually, I haven't tried virtual methods yet - but, I don't recall that inheritance was being used except for the Qt classes which I am not concerned with.)

For a toy program with only several functions, it is easy to use the mapping and sed to view a user-friendly calling sequence. But, for 1000's of functions/methods, you just have to write a program or script to create a map from the  nm output, and then programmatically change the addresses to the function/method names based on this map.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Duncan RoeSoftware DeveloperCommented:
Looks good! Will you be accepting your post as the solution?
0
phoffricAuthor Commented:
What I am doing now is just running the program under certain GUI operations, and then looking at the calling sequence after the program completes.

Alternatively, I think I can keep the program running continuously. I believe I could customize the two enter/exit functions to send the results to another program which transforms the results into a user-friendly active display as I am running the program.

Since the program is a simulation, I would probably have to set the Time Step to an artificially long period, say 20-60 seconds, to give me a chance to review the calling sequence depending upon what GUI buttons/text entries I would make.
0
phoffricAuthor Commented:
@Duncan

I didn't really understand your post and was going to discuss it with you when I discovered the -finstrument-functions compiler option, and pursued that approach. I have limited time at work to try things since they kick me out way too soon compared to everywhere else I worked - well, rules are rules :( :( .

If your approach satisfies the OP constraints, then I'd like to talk to you about it. I am on a crushing development effort at the moment to demonstrate that the lead's Model Description Document is sufficiently well-written that I can actually write a model from it; and I promised not to look at his model/code (which is the source of this question), so this effort is on hold for a little bit until I finish that section.

But I would like to understand what you were driving at in the next couple of weeks, if that's OK with you. I won't have time at work, but on a free weekend, I could come up with a toy foo/bar example and see what you are talking about.
0
Duncan RoeSoftware DeveloperCommented:
Fine, look forward to that,

Cheers ... Duncan.
0
Duncan RoeSoftware DeveloperCommented:
This appears to answer the Q and EE wants the Q closed.
phoffric - you can still post to this Q after it is closed (e.g. to pursue the expect path)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows 7

From novice to tech pro — start learning today.