Search code examples
gocgolibav

Unexpected execution of minimal Cgo application linked to libavformat


I have a minimal C program

#include <libavformat/avformat.h>

AVFormatContext *open(const char *url) {
    printf("URL %s\n", url);
    AVFormatContext *ctx = NULL;
    int err = avformat_open_input(&ctx, url, 0, 0);
    return ctx;
}

int main(int argc, char **argv) {
    open(argv[1]);
}

It works, it prints the file path I pass in, and returns a valid AVFormatContext.

I paste the code into a Golang program:

package main

// #include <libavformat/avformat.h>
//  AVFormatContext *open(const char *url) {
//  printf("URL %s\n", url);
//  AVFormatContext *ctx = NULL;
//  int err = avformat_open_input(&ctx, url, 0, 0);
//  return ctx;
//  }
//  #cgo LDFLAGS: -lavformat
import "C"
import (
    "fmt"
    "os"
)

func main() {
    fmt.Println("Lets try this")
    url := os.Args[1]
    C.open(C.CString(url))
}

This prints URL /dev/urandom (no matter what args I give it) and hangs. And very oddly, it does NOT print Lets try this. This is on a Mac using ffmpeg and go from homebrew:

ffmpeg version 4.2.1
Copyright (c) 2000-2019 the FFmpeg developers   
built with Apple clang version 11.0.0 (clang-1100.0.33.8)

go version go1.13.4 darwin/amd64

My current guesses are compiler ABI incompatibilities, or maybe libavformat running something before main()?


Solution

  • The problem was the function name open. It is masking the system call open, that go must be calling before it gets to main.