Go Back   Cockos Incorporated Forums > REAPER Forums > REAPER Developer Forum

Reply
 
Thread Tools Display Modes
Old 04-28-2014, 02:00 PM   #1
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default Reaper on Mac OS crashes when using certain command IDs with Main_OnCommand

Hi,
Does anyone have an idea as to why I would be getting "Bad_access" violation errors when passing certain command IDs to Main_OnCommand? In particular...
Trying to use Main_OnCommand with 41042, 41043, 41044 and 41045 (go measure/beat forward/backward). Strangely enough with all of the four commands I am getting "bad access" violation errors on Mac OS. All the other command IDs I tried seem to produce no such errors.
I made sure Main_OnCommand and, just in case, Main_OnCommandEx are initialized with the IMPAPI macro. Are there any other API functions that need to be initialized for making Main_OnCommand* calls to work? O, BTW, I am calling Main_OnCommand with these IDs from the CommandSelector hook function.

Some more information:
- I am compiling a C/C++ extension using Xcode 5.1.
- The OS is Mavericks (10.9.2).
- Reaper version is the latest (4.61.x).

Thanks for any help/suggestions.
Best,
Victor
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-01-2014, 12:29 PM   #2
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 10,321
Default

Can you provide a crash report? Call stack? etc...
Justin is offline   Reply With Quote
Old 05-01-2014, 10:39 PM   #3
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default Diagnostics log is attached

Thanks Justin.
I looked at the diagnostics log and it seems that, among other things, it contains a lot of calls to the Main_OnCommand and Main_OnCommandEx functions.
I am attaching the whole log here as you will probably be able to identify the cause much quicker.

Thanks a lot.
Victor
Attached Files
File Type: txt Reaper.txt (93.3 KB, 185 views)
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-05-2014, 10:07 PM   #4
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default Any ideas?

Anyone can help? Do you need any more information?
Thanks,
V
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-06-2014, 12:25 AM   #5
Jeffos
Mortal
 
Jeffos's Avatar
 
Join Date: Dec 2008
Location: France
Posts: 1,969
Default

Hi vtsaran, we'd need the code to make sure of it but I think you are just facing some code re-entrance issues...
You should protect your command hook against it (here's an example: https://code.google.com/p/sws-extens...tension.cpp#80)
Jeffos is offline   Reply With Quote
Old 05-06-2014, 07:04 AM   #6
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 10,321
Default

It appears your hook function is calling Main_OnCommand(), which is calling your hook function, which is calling Main_OnCommand(), which ... stack overflow.
Justin is offline   Reply With Quote
Old 05-11-2014, 12:16 AM   #7
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Jeffos View Post
Hi vtsaran, we'd need the code to make sure of it but I think you are just facing some code re-entrance issues...
You should protect your command hook against it (here's an example: https://code.google.com/p/sws-extens...tension.cpp#80)
This is more or less what I'm doing.
1. Register the hook with

if (!rec->Register("hookcommand", (void*)commandSelector)) {
// registering the hook function failed ...
}

2. In my commandSelector function, I am attempting to augment the actions for some default Reaper commands, like this:

static bool commandSelector(int commandId, int flag)
{
if (commandId == cidGoMeasureForward) {
Main_OnCommand(41042, 0);
// do some additional tasks here
return true;
} else if (commandId == cidGoMeasureBackward) {
Main_OnCommand(41043, 0);
// do some additional tasks here
return true;
} else if (commandId == cidGoBeatForward) {
Main_OnCommand(41044, 0);
// do additional tasks
return true;
} else if (commandId == cidGoBeatBackward) {
Main_OnCommand(41045, 0);
// do some additional tasks here
return true;
}

// not our command
return false;
}

the cid are defined using the #define directive, e.g.
#define cidGoMeasureForward 41042

The 41042 and 41043 crash Reaper when tied to shortcut keys, e.g. "page up" and "page down". The 41044 and 41045 work just fine no matter what shortcut keys I assigned them to.

Thanks for your help.
Victor
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-12-2014, 11:15 AM   #8
Justin
Administrator
 
Justin's Avatar
 
Join Date: Jan 2005
Location: NYC
Posts: 10,321
Default

Quote:
Originally Posted by vtsaran View Post
Code:
if (!rec->Register("hookcommand", (void*)commandSelector)) {
// registering the hook function failed ...
}

static bool commandSelector(int commandId, int flag)
{
  if (commandId == 41042) {
    Main_OnCommand(41042, 0);
    // do some additional tasks here
    return true;
  }
  // not our command
  return false;
}
The problem here is that Main_OnCommand() will call commandSelector, so you have infinite recursion. Probably the best way to deal with this would be to track the state to only check if you're not already in you function, such as:
Code:
int g_hook_depth;

static bool commandSelector(int commandId, int flag)
{
  if (!g_hook_depth && commandId == 41042) {
    g_hook_depth ++;
    Main_OnCommand(41042, 0);
    // do some additional tasks here
    g_hook_depth --;
    return true;
  }
  // not our command
  return false;
}
But this is not perfect either, i.e. it won't work in custom actions. You could possibly keep a stack of command calls, but that might cause other problems. The better way would be for us to add a post-action hook.
Justin is offline   Reply With Quote
Old 05-17-2014, 05:35 PM   #9
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Justin View Post
The problem here is that Main_OnCommand() will call commandSelector, The better way would be for us to add a post-action hook.
Do you think the post-action hook is something you guys would consider?
I guess, for the time being I will probably have to imitate the approach found in SWS extension where they seem to keep the stack of all commands relying on the WDL list utility.
I was just hoping I could keep it simple as I really only need several commands for what I'm trying to do.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-19-2014, 01:16 AM   #10
Jeffos
Mortal
 
Jeffos's Avatar
 
Join Date: Dec 2008
Location: France
Posts: 1,969
Default

I don't think a static WDL_PtrList like the one we use in SWS will help you here... It allows *some* recursion paths and prevent other ones a bit like Justin's solution above (except it only deals with sws actions, not native ones, e.g. a sws action "a" can call sws action "b" but, of course, "b" can neither call itself, nor "a").

There might be ways around it though... Can I ask what do you want to achieve exactly? i.e. what are those "additional tasks" you want to perform?
Jeffos is offline   Reply With Quote
Old 05-19-2014, 11:00 AM   #11
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Jeffos View Post
There might be ways around it though... Can I ask what do you want to achieve exactly? i.e. what are those "additional tasks" you want to perform?
It's actually pretty simple. I want to be able to perform a native or a custom command and then output its result to a built-in speech synthesizer. So instead of introducing my own command IDs and calling built-in functions, I would like to leverage existing IDs and execute those commands with Main_OnCommand.

Hope this makes sense.
Victor
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-19-2014, 11:18 AM   #12
Banned
Human being with feelings
 
Banned's Avatar
 
Join Date: Mar 2008
Location: Unwired (probably in the proximity of Amsterdam)
Posts: 4,868
Default

^^ That sounds pretty cool, Victor. Thumbs up for improving accessibility!

Can I also put in a vote for something post-action in the form of feedback via the OSC Control Surface for 'action descriptions' like "ACTION"? That way we could build such things (and much more) without having to build extensions. Which would be a double win for accessibility, I guess.
__________________
˙lɐd 'ʎɐʍ ƃuoɹʍ ǝɥʇ ǝɔıʌǝp ʇɐɥʇ ƃuıploɥ ǝɹ,noʎ
Banned is offline   Reply With Quote
Old 05-19-2014, 11:52 AM   #13
Jeffos
Mortal
 
Jeffos's Avatar
 
Join Date: Dec 2008
Location: France
Posts: 1,969
Default

Quote:
Originally Posted by vtsaran View Post
It's actually pretty simple. I want to be able to perform a native or a custom command and then output its result to a built-in speech synthesizer. So instead of introducing my own command IDs and calling built-in functions, I would like to leverage existing IDs and execute those commands with Main_OnCommand.

Hope this makes sense.
Victor
Thanks for the details Victor. Very interesting project, and yes, it makes sense, totally! Given your description, I can't see any workaround though: the post-hook Justin mentioned is definitely the way to go in this case. Can't promise anything except I'll have a look...
Jeffos is offline   Reply With Quote
Old 05-19-2014, 12:08 PM   #14
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Jeffos View Post
in this case. Can't promise anything except I'll have a look...
Thanks for any help with this.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 05-24-2014, 01:10 PM   #15
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default I will work around for the time being

I decided to work around the limitation for now and rely on API methods to do what I want to do. A bit more work, but I get a chance to learn more of SDK.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 06-05-2014, 06:32 AM   #16
Jeffos
Mortal
 
Jeffos's Avatar
 
Join Date: Dec 2008
Location: France
Posts: 1,969
Default

vtsaran, the post action hook thing is available in v4.70pre (http://forum.cockos.com/showthread.php?t=22836).
For more details, look for "hookpostcommand" in the generated reaper_plugin_functions.h
Jeffos is offline   Reply With Quote
Old 07-14-2014, 11:34 AM   #17
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

A strange thing happens. When I generate the latest reaper_plugin_function.h from Reaper 4.7 and plug it into my existing project, I get a lot of errors. For one, there is a reference to the WDL_FastString class. However, even after resolving this problem, I am getting a bunch of errors from RPR_MIDI and other classes in reaper_plugin_function.h.
What version of WDL should I be using now? When I tried the latest (Git) source from the Cockos site, the errors didn't go away.

Thanks for any help.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 07-14-2014, 01:52 PM   #18
Breeder
Human being with feelings
 
Join Date: Nov 2010
Posts: 1,809
Default

Delete SWS and try generating it again.
Breeder is offline   Reply With Quote
Old 07-14-2014, 07:44 PM   #19
fingers
Human being with feelings
 
fingers's Avatar
 
Join Date: Dec 2009
Location: Wellington, NZ
Posts: 299
Default

WDL_FastString and whatever other pointers used by SWS are opaque so a simple:
Code:
class WDL_FastString;
class RprMidiNote;
class Whatever;
#include "reaper_plugin_functions.h"
should get around it.
fingers is offline   Reply With Quote
Old 07-14-2014, 08:50 PM   #20
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Breeder View Post
Delete SWS and try generating it again.
I am not really using SWS, writing my own extension.
I wish I was able to compile SWS, but that's a different topic altogether.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 07-15-2014, 06:24 AM   #21
Breeder
Human being with feelings
 
Join Date: Nov 2010
Posts: 1,809
Default

Quote:
Originally Posted by vtsaran View Post
I am not really using SWS, writing my own extension.
But the question is not if you use it, only if you have it installed. Because if you do, header will also include functions SWS exports...rest is in the Fingers' post
Breeder is offline   Reply With Quote
Old 07-27-2014, 01:48 PM   #22
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Quote:
Originally Posted by Jeffos View Post
vtsaran, the post action hook thing is available in v4.70pre (http://forum.cockos.com/showthread.php?t=22836).
For more details, look for "hookpostcommand" in the generated reaper_plugin_functions.h
Hi Jefos,
I just got a chance to look at the newly-implemented HookPostCommand functionally.
Can you help me understand what I would put inside the callback it needs? Do I pass in the same command IDs I wanted to use with main_oncommand and, if yes, what would I do with them inside this callback?

Thanks,
Vic
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Old 07-29-2014, 03:34 AM   #23
Jeffos
Mortal
 
Jeffos's Avatar
 
Join Date: Dec 2008
Location: France
Posts: 1,969
Default

^ sorry vtsaran I do not understand the question, but here's how it works, let me know if it isn't clear enough...

1) You need a recent REAPER version, say v4.71

2) In your plugin extension entry point, you can add:

Code:
rec->Register("hookpostcommand", (void*)hookPostCommandProc);
... where "hookPostCommandProc" is a callback you have to define too, here's a stupid example:
Code:
void hookPostCommandProc(int iCmd, int flag)
 {
 	WDL_FastString str;
 	str.SetFormatted(512, "hookPostCommandProc: %s, flag=%d\r\n", kbd_getTextFromCmd(iCmd, NULL), flag);
 	ShowConsoleMsg(str.Get());
 }
^ this example just displays action names as soon as they are performed by the user. In your case this is where you want to hook the built-in speech synthesizer. "iCmd" is the command (of the main section) that has been performed by the user.

___

About the SWS discussion above... SWS will soon compile "out of the box": in REAPER v4.72pre2+, the API functions header file will not contain functions exported by 3rd party extensions (like SWS) anymore -- unless you tick a new option when generating the said .h
Jeffos is offline   Reply With Quote
Old 07-29-2014, 03:54 PM   #24
vtsaran
Human being with feelings
 
Join Date: Jan 2011
Posts: 41
Default

Hello Jeffos,
Thanks for your help, however...
I am not sure how this solves my initial problem, which is that using Main_OnCommand when used from inside the "hookcommand" and "hookcommand2" callbacks crash Reaper. This, as I understand, is a result of the recursion.
When I attempted to call Main_OnCommand from the "hookpostcommand" callback, I got the same result, Reaper crash.
__________________
--- --- ---
Visit me at http://www.victortsaran.net
vtsaran is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:58 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2017, vBulletin Solutions Inc.