1

I am trying to set up logging in LibVLC, and am running into some problems.

The function I am using is libvlc_log_set_file, here are the docs: LibVLC logging docs

Here is the code I have now:

//header
private:
    FILE * logFile;

//source
logFile = fopen(path.c_str(), "w");
if(logFile != NULL)
{
    libvlc_log_set_file(_libvlc_instance, logFile);
}

On the libvlc_log_set_file line I get this error, "Unhandled exception at 0x77559E33 (ntdll.dll) in nw.exe: 0xC0000005: Access violation writing location 0x00000014."

I am able to open and write to the file with fputs() just fine.

I am using NW.js with WebChimera.js compiling to 32 bit with Visual Studio 2013 on a 64 bit Windows 7 machine.

Any ideas?

cascade256
  • 41
  • 6

1 Answers1

0

I had this exact problem today. I was unable to solve it using libvlc_log_set_file. I instead chose to use libvlc_log_set to set up the callback and use that method to write to a log file instead. Here is a example, it shows what needs to be done. I don't recommend the global file pointer, it is just for this quick sample.

Note: logpath is a const char* that contains the path of your log file. Also, you probably want to flockfile to make this thread safe. You can also toss a switch statement in there to handle the level parameters for LIBVLC_NOTICE, LIBVLC_ERROR, LIBVLC_WARNING and LIBVLC_DEBUG to give your logging some granularity.

bool g_loggingEnabled = true;
FILE* g_logfp = nullptr;

void logcb(void *data, int level, const libvlc_log_t *ctx, const char *fmt, va_list args)
{
    if (!g_loggingEnabled) return;

    if (g_logfp == nullptr)
    {
        errno_t err = fopen_s(&g_logfp, logpath, "w");

        if (err != 0)
        {
            g_loggingEnabled = false;
            return;
        }
    }

    vfprintf(g_logfp, fmt, args);
}

Addendum: On Windows you might want to use CreateFile instead with the FILE_SHARE_READ flag set and use WriteFile so that external text editors can view the file while the logging is occurring in real-time. If you do, look into vsprintf_s instead of vfprintf to fill a character buffer that you would then pass to WriteFile in the logcb method.

  • Thanks! It works great. The tips on implementing it are greatly appreciated. – cascade256 Jul 15 '15 at 23:54
  • Also worth noting that in VS 2013 %zd and %zu aren't support specifiers by vsnprintf_s etc., but libvlc uses them to pass you integer values. I asked Jean Baptiste, head of VLC, about this and he said that VS 2015 should handle these specifiers. I haven't tried that yet, at work here they have me on VS 2013. What I did instead is search and replace %zd and %zu with %Id and %Iu, but I'm using String^ capabilities like .Replace in C++/CLI and then marshal_context as const char* the fmt which makes that painless. I don't necessarily recommend that approach, but I have to demo soon. – Nelson Rush Jul 17 '15 at 21:12
  • I found a decent way of handling the log levels without a switch by placing the following line at the top of the method after the logging enabled line. Where g_loggingLevel is LIBVLC_DEBUG or whatever you want your level to be. It works because each level is above the other numerically in an enum. Note: It might break if they ever changed the values so they aren't consecutive, but that's unlikely. `if (g_loggingLevel > level) return;` – Nelson Rush Jul 17 '15 at 21:20
  • Unfortunately, I had to downgrade from VS2015 to VS2013 for compatibility with NW.js, so thanks for the heads up on the formatting. In other libraries I have used, the logging levels are just stored as '`int` so I assumed it was the same. Glad it works anyway! – cascade256 Jul 19 '15 at 02:34
  • When you pass initialization arguments to the libvlc_new method, you can toss in a "-vvv" to get more verbosity. The number of v you provide determine how litte or how much more information you get. This is useful if you are struggling to figure out what is going wrong in the libvlc or its plugins. – Nelson Rush Jul 20 '15 at 14:52