[ 
https://issues.apache.org/jira/browse/THRIFT-5727?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Hooman Vassef updated THRIFT-5727:
----------------------------------

Let's say I have a serviceA that extends another, serviceB. The generated code 
will look something like this:

```
template <class Protocol_>
bool 
serviceAProcessorT<Protocol_>::dispatchCall(::apache::thrift::protocol::TProtocol*
 iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, 
int32_t seqid, void* callContext) {
  typename ProcessMap::iterator pfn;
  pfn = processMap_.find(fname);
  if (pfn == processMap_.end()) {
    return  ::serviceBProcessorT<Protocol_>::dispatchCall(iprot, oprot, fname, 
seqid, callContext);
  }
  (this->*(pfn->second.generic))(seqid, iprot, oprot, callContext);
  return true;
}

template <class Protocol_>
bool serviceAProcessorT<Protocol_>::dispatchCallTemplated(Protocol_* iprot, 
Protocol_* oprot, const std::string& fname, int32_t seqid, void* callContext) {
  typename ProcessMap::iterator pfn;
  pfn = processMap_.find(fname);
  if (pfn == processMap_.end()) {
    return  ::serviceBProcessorT<Protocol_>::dispatchCallTemplated(iprot, 
oprot, fname, seqid, callContext);
  }
  (this->*(pfn->second.specialized))(seqid, iprot, oprot, callContext);
  return true;
}
```

Let's also say that we use `templates=only`.

Looking closely at `serviceA::dispatchCallTemplated()`, when serviceA's 
function lookup falls through to delegate it to the parent, it calls 
`serviceB::dispatchCall()`, not `serviceB::dispatchCallTemplated()`. With 
`templates=only`, this will result in serviceB calling a `generic` function 
pointer that is NULL.

A comment hinting at some awareness of the problem can be found at this line:
https://github.com/apache/thrift/blob/45764096573890ef4c84bebf7499d51891746034/compiler/cpp/src/thrift/generate/t_cpp_generator.cc#L3325C1-L3325C1

In the general case, the question of whether the generated code should call 
`dispatchCall()` or `dispatchCallTemplated()` might depend on the combinations 
of a generic or specialized service extending another generic or specialized 
service (that being said, there are other comments in the code hinting at an 
assumption that the service specialization matches between the original and 
extended services).

But in the specific case of the `templates=only` option, it would seem that 
`dispatchCallTemplated()` should always call its parent's 
`dispatchCallTemplated`, should it not?

> templates=only + extends = segfault
> -----------------------------------
>
>                 Key: THRIFT-5727
>                 URL: https://issues.apache.org/jira/browse/THRIFT-5727
>             Project: Thrift
>          Issue Type: Bug
>          Components: C++ - Compiler
>    Affects Versions: 0.13.0
>            Reporter: Hooman Vassef
>            Priority: Major
>
> When the `templates=only` option is given (if not always), in the `extends` 
> case, should `dispatchCallTemplated()` always call its parent's 
> `dispatchCallTemplated()` (instead of `dispatchCall()`?



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to