By throwing an exception you should be able to obtain the full (functions) callstack. I've described part the process in a [section of the documentation of my library plugin][1] along with the related functions I provide to decode `v:throwpoint`. IIRC, there is another Q/A where I delved more in details about how its works... Found [it](https://vi.stackexchange.com/questions/25936/getting-the-line-number-and-function-name-of-a-function-caller)! And also [here](https://vi.stackexchange.com/questions/6019/is-it-possible-to-populate-the-quickfix-list-with-the-errors-of-vimscript-functi).

There are a few limitations: it only returns calling functions. If your function is called only through commands or mappings, you won't see anything useful. It's also extremely slow: do not abuse of the feature.

EDIT: it seems that `v:throwpoint` and Vim 8.2.1297 `expand('<stack>')` return a string (almost) in the same format. Split it at `..`. Then each element will contain a function name (and may a line number). From there the best way to know where it's defined is with `verbose function {funcname}`. The difficulty is that the message will be localized, and sometimes anonymous functions have already been garbage collected (or why I don't use them any more). 

My library already takes care of all these issues. I'll eventually upgrade it to use `expand('<stack>')` whenever it's possible as I expect better performances.

  [1]: https://github.com/LucHermitte/lh-vim-lib/blob/master/doc/Callstack.md