yse / easy_profiler

Lightweight profiler library for c++
MIT License
2.19k stars 189 forks source link

Profiler GUI says 'Cannot read profiled blocks' #115

Open christau opened 6 years ago

christau commented 6 years ago

Hi All, I don't know what I'm doing wrong. I'm having an application that statically links some libs and I'm trying to profile some code inside these libs. I followed the guide, and enabled the profiler like this in my main function:

int main(int argc, char** argv)
{
EASY_FUNCTION(profiler::colors::Magenta);
EASY_PROFILER_ENABLE;
profiler::startListen();

Then over in my render thread (which is a statically linked lib) I added following code:

void renderer::thread::run() noexcept {
    EASY_MAIN_THREAD;
    EASY_FUNCTION(profiler::colors::Green);

And in the render loop I added this code:

    while (_active.load()) {
        EASY_BLOCK("Render loop");

Then I start the application (compiled in release mode) and atttach the profiler GUI to the running process (Clicking 'connect' button). After a while I'm stopping the capture by closing the 'Capturing frames...' dialog. Right after this, a dialog pops up, telling me 'Cannot read profiled blocks'. snap

Can anyone tell me what I did wrong? My aim is to measure the timing of the render loop. Many thanks in advance for help.

bsviglo commented 6 years ago

I see the same problem on my per project and also don't know what I'm doing wrong

cas4ey commented 6 years ago

Hi guys,

I appologise for the delay.

Please, try to build and launch _profilersample (uncomment //#define SAMPLE_NETWORK_TEST here before building it to permit gui to connect to profiler_sample) and profile it. Is it working for you?

Can you check if BUILD_WITH_EASY_PROFILER macro is defined?
If not, try to add target_compile_definitions(${YOUR_PROJECT} PUBLIC -DBUILD_WITH_EASY_PROFILER=1)

christau commented 6 years ago

Thanks very much for your reply. Indeed, the sample is running fine. I added -DBUILD_WITH_EASY_PROFILER=1 but it is still the same behaviour. I also followed the sample and tried to set the easy profiler macros accordingly in my code. But I did not have any success yet. Well I keep trying and let you know if I succeed.

cas4ey commented 6 years ago

Does v1.3.0 have the same behavior?

christau commented 6 years ago

I checked out and built/installed v1.3.0, but it has the same behaviour.

cas4ey commented 6 years ago

OK, that means that there are some integration/usage problems.

Which platform do you use? Windows?
Is easy_profiler built as static lib or as shared lib (dll)? On WIndows easy_profiler should be built as shared lib and should be linked dinamically only. You can link it to static libs, but the profiler itself should be linked dynamically.

Try to remove EASY_FUNCTION and EASY_PROFILER_ENABLE from main() function, profiler::startListen() should be enough.

cas4ey commented 6 years ago

@christau could you give some more details, please?

christau commented 6 years ago

Sorry for the delay and thank you for the reminder. I did not have time at the moment to make your suggested changes. I'm using it on Linux (Ubunt 16.04) and I'm dynamically linking the easy_profiler.so. My project is based on CMake.

gr8parker commented 6 years ago

Hi. Had this problem yesterday. Easy profiler was compiled under Qt5.10 as well as my project. Roll back to Qt5.9.1 helped me.

christau commented 6 years ago

@gr8parker I'm using Qt5.5. So I guess the version shouldn't be the problem.

ArthurGoodman commented 6 years ago

@christau I've figured this out. This error will appear if you have at least one unclosed block, when you finish capturing. So, for example, if you have an EASY_FUNCTION(...) call in your run() method, and when you finish profiling, this method is still running, which it probably is, you gonna get this error.

ArthurGoodman commented 6 years ago

So, yeah... Actually, maybe it is indeed a bug, because there's no way to guarantee that all blocks are closed when user hits Stop. Anyway, I fixed it in my application by removing all blocks that definitely not going to get closed during profiling. And also, it's probably a good idea to make that error message more relevant and informative.

cas4ey commented 6 years ago

@ArthurGoodman you're damn right! I have completely forgot about this.

This is an expected behavior. Top-level blocks are treated as "frames" and incomplete frames are not sent to the UI because such frames breaks statistics and histogram (because it's duration will differ from the rest of frames and will affect average stats).
It is also a problem to start profiling in the middle of executing frame - such cut frame will also break statistics due to the same reasons, - such frames are also thrown off.

By the way, what is the point of using blocks which are never going to be finished?

P.S.: Since profiler ui now supports saving snapshots, such incomplete frames could be removed by user manually and I can add an option to store such frames (despite it requires some additional effort). But it will not help very much for blocks which are never going to finish.

ArthurGoodman commented 6 years ago

@cas4ey Yes, your are right, such blocks have no use, but the problem is that the error message is completely uninformative for that situation. I was just blindly putting a block into every function, and it took me some time to figure out what was the reason :)

Levi-Armstrong commented 2 years ago

@cas4ey I am running into the same issue which I think is related but not sure if this is possible to resolve. I have an application I am profiling and 90% I get the error message above about unable to read profile blocks. Sometime I can start and stop it and get data but it is very rare. My applications have several threads with profile blocks in them which are most likely not finished when I hit stop. Is this the reason I am not getting data?