Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find indirect calls to specific built-in MATLAB function

What do I want?

I am looking for a way to detect all points in my code where a specific function is called.

Why do I want it?

Some examples:

  • Some output comes out sorted or randomized, and I want to know where this happens
  • I am considering to change/overload a function and want to know in which part of my code this could have impact

What have I tried?

  • I tried placing a breakpoint in the file that was called. This only works for non builtin functions which are called from short running code that always executes everything.
  • I tried 'find files', this way I can easily find direct calls to sort but it is not so easy to find a call to sort invoked by unique for example.
  • I have tried depfun, it tells me:
    • whether something will be called
    • from where non-builtin functions will be called
  • I thought of overloading the builtin function, but feels like a last resort for me as I am afraid to make a mess. | Edit: Also it probably won't help due to function precedence.

The question

What is the best way to track all potential (in)direct function calls from a specific function to a specific (built-in)function.

like image 465
Dennis Jaheruddin Avatar asked Jan 06 '14 16:01

Dennis Jaheruddin


People also ask

What is the built in function in MATLAB?

A built-in function is part of the MATLAB executable. MATLAB does not implement these functions in the MATLAB language. Although most built-in functions have a . m file associated with them, this file only supplies documentation for the function.

What is an indirect function call?

If the linker encounters an indirect function call (by a pointer to function), it assumes that any of the functions addresses of which were taken anywhere in the program, can be called at that point.

How do you pass a function handle in MATLAB?

To create a function handle, use the @ operator. For example, create a handle to an anonymous function that evaluates the expression x2 – y2: f = @(x,y) (x.


2 Answers

I don't exactly understand your use case, but I guess most of the information you want can be obtained using dbstack, which gives you the call-stack of all the parent functions calling a certain function. I think the easiest way is to overload built-in functions something like this (I tried to overload min):

function varargout = min(varargin)

% print info before function call
disp('Wrapped function called with inputs:')
disp(varargin)
[stack,I] = dbstack();
disp('Call stack:')
for i=1:length(stack)
    fprintf('level %i: called from line %i in file %s\n', ...
        i, stack(i).line, stack(i).file);
end

% call original function
[varargout{1:nargout}] = builtin('min', varargin{:});

% print info after function call
disp('Result of wrapped function:')
disp(varargout)

I tried to test this, but I could not make it work unfortunately, matlab keeps on using the original function, even after playing a lot with addpath. Not sure what I did wrong there, but I hope this gets you started ...

like image 58
Bas Swinckels Avatar answered Nov 15 '22 03:11

Bas Swinckels


Built-in functions take precedence over functions in local folder or in path. There are two ways you can overload a built-in for direct calls from your own code. By putting your function in a private folder under the same directory where your other MATLAB functions are. This is easier if you are not already using private folder. You can rename your private folder once you are done investigating.

Another way is to use packages and importing them. You put all your override functions in a folder (e.g. +do_not_use). Then in the function where you suspect built-in calls are made add the line "import do_not_use.*;". This will make calls go to the functions in +do_not_use directory first. Once you are done checking you can use "clear import" to clear all imports. This is not easy to use if you have too many functions and do not know in which function you need to add import.

In addition to this, for each of the function you need to follow Bas Swinckels answer for the function body.

Function precedence order.

Those two methods does not work for indirect calls which are not from your own code. For indirect calls I can only think of one way where you create your own class based on built-in type. For example, if you work only on double precision types, you need to create your own class which inherits from double and override the methods you want to detect. Then pass this class as input to your code. Your code should work fine (assuming you are not using class(x) to decide code paths) since the new class should behave like a double data type. This option will not work if your output data is not created from your input data. See subclassing built-in types.

like image 25
Navan Avatar answered Nov 15 '22 05:11

Navan