HydrogenAudio

Hosted Forums => foobar2000 => Development - (fb2k) => Topic started by: dasmo90 on 2015-02-12 20:35:12

Title: Problems using metadb_handle::get_path()
Post by: dasmo90 on 2015-02-12 20:35:12
Hi,

I am using the latest foobar2000 SDK (from 14/1/2015) with VS Express 2013 and foobar2000 player v1.3.7.

I have a problem using the metadb_handle::get_path() method to retrieve the absoulte path of an audio file. The method works perfectly well in Debug mode, but my programm crashes in Release mode.

An example:
Code: [Select]
virtual void on_playback_new_track(metadb_handle_ptr p_track) {

    console::formatter() << p_track->get_path();
}


On top of the call stack is

>foo_social_playlist.dll!title_changer::on_playback_new_track(service_ptr_t<metadb_handle> p_track) Line 135   C++

so I can't discover the problem. Can someone help me?
Title: Problems using metadb_handle::get_path()
Post by: Zao on 2015-02-12 22:29:14
Are you doing anything related to playback control elsewhere? You may be changing playback state where you're not allowed to, resulting in fallout in callbacks like this one.

Also check if you're doing playlist operations or metadb operations where you should not.

What kind of tracks are in the list while doing this, and are their inputs well-behaved? Can you reproduce it in a fresh portable installation with just your component?
Title: Problems using metadb_handle::get_path()
Post by: dasmo90 on 2015-02-13 00:57:29
Thanks for the speedy answer!

I solved the problem, but I really don't understand, what the actual problem was.

I am using the mainmenu_commands class. And for some reason the following code change prevents the program crash.

Before:
Code: [Select]
class my_mainmenu_commands : public mainmenu_commands {
...
virtual void execute(t_uint32 p_index, service_ptr_t<service_base> p_callback) {
        if (p_index == 0) {
            some_method();
        }
    }
};

// this method is in another .cpp file
void some_method() {
    // do stuff
}


After:
Code: [Select]
class my_mainmenu_commands : public mainmenu_commands {
...
virtual void execute(t_uint32 p_index, service_ptr_t<service_base> p_callback) {
        if (p_index == 0) {
            exec(); // using static "helper" method
        }
    }
};

static void exec() {
    some_method();
}
Title: Problems using metadb_handle::get_path()
Post by: dasmo90 on 2015-02-13 12:10:39
I spent some time in finding the real problem and I found out the following:

In my program I want to fetch a metadb_handle_ptr object with help of the file path. To achieve this I used the following code (which works in Debug mode, but NOT in Release mode):
Code: [Select]
// get a playable location object
playable_location_impl pl = playable_location_impl();
// setting the path
pl.set_path(path.c_str());

// create the metadb_handle_ptr object
metadb_handle_ptr track;
static_api_ptr_t<metadb>()->handle_create(track, pl);


After removing this code everything works fine. (I also undid the previous "fix" using the static exec() method.)

What is the problem in using this code? Is there an alternative way of fetching a metadb_handle_ptr object with help of the file path?
Title: Problems using metadb_handle::get_path()
Post by: Peter on 2015-02-17 12:28:30
I attempted to migrate entire foobar2000 source code to VS2013 and encountered the same problem.

This is caused by a bug in VS2013 optimizer, miscompiling playable_location methods; as an effect all metadb_handle::get_path() calls return nonsensical values and cause crashing.

One solution to this issue is to disable whole program optimization:
Project Properties => Configuration properties => General => Whole Program Optimization: "No Whole Program Optimization"

An alternative would be to use another version of the toolchain. VS2010 was used for all foobar2000 development for a long time without known bugs. VS2015 has not yet been tested.
Title: Problems using metadb_handle::get_path()
Post by: dasmo90 on 2015-02-17 17:10:01
Thanks for the answer!

This solved the problem.
Title: Problems using metadb_handle::get_path()
Post by: Peter on 2015-02-18 09:56:30
Update, tried VS2015 CTP 5, after getting it to actually compile our source tree, I can see that it has the same bug.
Title: Problems using metadb_handle::get_path()
Post by: musicmusic on 2015-02-18 14:01:53
It's worth reporting it on Microsoft Connect (if not already):

https://connect.microsoft.com/VisualStudio/Feedback (https://connect.microsoft.com/VisualStudio/Feedback)

There are some other /GL bugs there though I didn't see anything involving virtual functions.
Title: Problems using metadb_handle::get_path()
Post by: Peter on 2015-02-19 10:51:16
(Hi musicmusic!)

Posted with a proper isolated sample-
https://connect.microsoft.com/VisualStudio/...dll-environment (https://connect.microsoft.com/VisualStudio/feedback/details/1138028/incorrect-c-class-method-devirtualization-in-a-multi-dll-environment)
Title: Problems using metadb_handle::get_path()
Post by: musicmusic on 2015-02-25 19:14:44
Yes, hello.

The bug report seemingly disappeared from public sight a couple of days ago. Or, at least, it forces me to login and then gives an error.

Any idea what happened?

[edit] Hmm, never mind, it seems to be back now.
Title: Problems using metadb_handle::get_path()
Post by: Peter on 2015-02-26 12:06:11
Was indeed invisible (page not found) for a couple of days.... no idea what for. I hope the compiler behavior gets fixed.
Title: Problems using metadb_handle::get_path()
Post by: musicmusic on 2015-03-14 23:19:48
I noted the resolution of the bug report.

Perhaps it's this one they're saying it's a duplicate of?
https://connect.microsoft.com/VisualStudio/...Details/1106775 (https://connect.microsoft.com/VisualStudio/Feedback/Details/1106775)
Title: Problems using metadb_handle::get_path()
Post by: musicmusic on 2015-03-20 18:41:14
Well, Microsoft replied to the bug I linked:
Quote
Posted by Microsoft on 19/03/2015 at 17:48
Hi,

Thank you for reporting this issue. It was caused by a bug in the analysis used by the de-virtualization optimization (which is run for LTCG compiles) to determine whether replacing a virtual call with a direct one is safe or not. The analysis, called Invasion Analysis, determines if an instance of an object of a particular class/struct/union type enters the binary from another dll. The bug has already been fixed and the fix will be available in the next release of the VC++ compiler.

VC++ Compiler Team
Title: Problems using metadb_handle::get_path()
Post by: 3dyd on 2015-07-27 15:45:40
Does VS2013 Update 5 still have this issue? (Somehow I cannot reproduce it with Update 4)