The expansion of $@ in local args="$@" is unspecified by the POSIX standard. The bash shell will create a single space-delimited string containing all the positional parameters as the value for the args variable, while dash will try to execute local args="$1" "$2" "$3" (etc.)
The zsh and ksh shells behave like bash (creating a single string out of the positional parameters, although zsh would use the first character of $IFS for the delimiter) while the yash shell behaves like dash, at least in their default configurations.
In your case, you should use
my_func () {
local args
args="$*"
printf 'args: <%s>\n' "$args"
}
or
my_func () {
local args="$*"
printf 'args: <%s>\n' "$args"
}
I'm using $* here to make it obvious that I'm constructing a single string from a list of values. The string will contain the values of the positional parameters, delimited by the first character of $IFS (a space by default).
I'm also using printf to be sure to get the correct output of the user-supplied values (see Why is printf better than echo?).
Also, your script should use #!/bin/dash as the first line rather than #!/bin/sh as local is an extension to the standard sh syntax.