Log in

View Full Version : What is the easiest way to debug an AVS plugin?


Mitra
5th July 2024, 17:56
I'm building my first Avisynth plugin in Visual Studio 2019, but I'm stuck on debugging it, and all the documentation I've found is outdated.

wonkey_monkey
5th July 2024, 19:09
IIRC, 1) select Debug build (not strictly necessary I think, but it gives you more info), 2) add a Post-Build Event which copies the built DLL to the Avisynth+ plugin folder, e.g.:

copy $(TargetPath) "C:\Program Files (x86)\AviSynth+\plugins64\$(TargetFileName)"

then 3) in the Debugging section of the Project Properties, set Command to the path of the VirtualDub executable, AVSPMod, or whatever you want to run to test the plugin with (you could also set the command to run AVSMeter with a script that calls your plugin). Make sure you point it to an executable with a matching architecture.

When you press F5, Visual Studio will build the DLL, copy it to Avisynth+, run your command, and if your plugin crashes Visual Studio should be able to show you where.

Mitra
5th July 2024, 19:30
IIRC, 1) select Debug build (not strictly necessary I think, but it gives you more info), 2) add a Post-Build Event which copies the built DLL to the Avisynth+ plugin folder, e.g.:.....

Thank you! However, VS gets this error:

Exception thrown at 0x00007FF89D4DE78F (AviSynth.dll) in Veedub64.exe: 0xC0000005: Access violation reading location 0x0000000000000001.

and breakpoints don't work.

wonkey_monkey
5th July 2024, 19:33
If you delete your plugin's DLL from the Avisynth folder and hit F5 again (it shouldn't build and copy again as long as you haven't edited the source), does the error still happen?

Mitra
5th July 2024, 19:48
If you delete your plugin's DLL from the Avisynth folder and hit F5 again (it shouldn't build and copy again as long as you haven't edited the source), does the error still happen?

Yes, The plugin builds, dll and pdb files are copied by post-build event, VirtualDub runs, but when I open the script, it gives the same error again.

wonkey_monkey
5th July 2024, 19:51
If you haven't edited the source since the last build, then pressing F5 should only launch debugging again, without building and without copying the DLL.

What happens if you open VirtualDub yourself, outside of Visual Studio, and try to open a dummy script which only calls colorbars (this is with your plugin DLL in place in the plugins folder, not deleted)?

Mitra
5th July 2024, 20:06
What happens if you open VirtualDub yourself, outside of Visual Studio, and try to open a dummy script which only calls colorbars (this is with your plugin DLL in place in the plugins folder, not deleted)?

Outside of Visual Studio, VirtualDub works if the script is not contains my plugin. But if it contains my plugin, it gets error.

My plugin is located in the plugins folder and has not been deleted.

DTL
5th July 2024, 21:39
You debug plugin as standard DLL loaded to address space of a parent process. Where parent process typically some AVS-using application. It may be any application opening AVS scripts.

First leave debug dll in the default debug folder and simply load it with LoadPugin() in your script. Put your script in the same debug build folder.

To make debugging faster - set path to VirtualDub .exe in the debugging executable path and set command arguments to your script name. Also be sure working folder is default to project (or set manually to the folder with debug build). So at the debug start - VisualStudio will auto-load VirtualDub and it will load script and AVS environment will try to load your plugin. If script is not autoloaded - it looks something is wrong with current working dir settings in VS but you can still load it manually from File->Open in VirtualDub (slower but working too).

Set breakpoint to the plugin init (class constructor). The breakpoint must break at the startup where AVS load plugins and init classes. If not break (breakpoint is not active) - most typical reason your plugin binary (currently loaded into process space) is not match current sources so VS debugger do not work with this binary. So working from debug build folder ensure you use current built binary and not outdated (VS tracks if you change source and not make new build). If you use remote debugging - you need to auto-deploy every new build to executable host or copy files manually before starting each new debug after any sources changes. It looks debugger checks some unique build signature and refuse activating breakpoints if build do not match source.

After class init breakpoint is checked and working OK - you can continue execution and wait for error-break (VS debugger expected to catch it before VD handler).

Other possible way to debug with sources: Make debug build (with debugging information) at one host and run VirtualDub from VS debugger and try to get crash at exectution. If it happen in your plugin address space the VS will break and show source position (and other information). But you need to keep sources path unchanged (reference to sources looks like stored in the debug build executable).

Mitra
5th July 2024, 23:39
Finally, I was able to make progress my plugin with the help of wonkey_monkey and DTL.

@wonkey_monkey, and @DTL, I'm grateful for your help and explanations, Thank you very much.

Visual Studio still throws the same error. However, I noticed that if I don't focus on it and press F5 a few times, the error disappears and the breakpoints work.

StainlessS
8th July 2024, 10:29
Perhaps also of use,

#define BUG // switch on DPRINTF if defined, or comment out, ie precede with comment //

// below, either in a header, or in source

#ifdef BUG
// Call as eg DPRINTF("Forty Two = %d",42) // No Semi colon
// C99 Compiler (eg VS2008, and later)
#define DPRINTF(fmt, ...) dprintf(fmt, ##__VA_ARGS__); // No Semi colon needed
#else
// C99 Compiler (eg VS2008, and later)
#define DPRINTF(fmt,...) /* fmt */
#endif

extern int __cdecl dprintf(char* fmt, ...);


// below, in source file


int __cdecl dprintf(char* fmt, ...) {
char printString[2048]="Mitra-Thingy: "; // Must be nul Termed, eg "Test: " or ""
char *p=printString;
for(;*p++;);
--p; // @ null term
va_list argp;
va_start(argp, fmt);
vsprintf(p, fmt, argp);
va_end(argp);
for(;*p++;);
--p; // @ null term
if(printString == p || p[-1] != '\n') {
p[0]='\n'; // append n/l if not there already
p[1]='\0';
}
OutputDebugString(printString);
return int(p-printString); // strlen printString
}


// Usage, dprintf("%s, %d + %d = %d","Hello",1,2,3); // WITH Trailing semi colon
// Outputs to debug (Visual Studio debug, OR DebugView (Google DebugView)
// OUTPUT "Hello, 1 + 2 = 3"
// dprintf(), always causes output

// Usage, DPRINTF("%s, %d + %d = %d","Hello",1,2,3) // No Trailing semi colon
// Outputs to debug (Visual Studio debug, OR DebugView [Google DebugView])
// OUTPUT "Hello, 1 + 2 = 3"
// DPRINTF(), only causes output if BUG defined


Useful for status, where it got to so far. (undefine BUG, removes all DPRINTF debug output)

EDIT: Same-ish usage as printf(), %s for string, %d for int, %f for floats.

Mitra
8th July 2024, 19:55
Perhaps also of use,
.....

Useful for status, where it got to so far. (undefine BUG, removes all DPRINTF debug output)

EDIT: Same-ish usage as printf(), %s for string, %d for int, %f for floats.

:thanks: