| 174 | } |
| 175 | |
| 176 | int |
| 177 | PyThread::inferTidFromPThreadStructure( |
| 178 | const std::shared_ptr<const AbstractProcessManager>& manager, |
| 179 | unsigned long pthread_id) |
| 180 | { |
| 181 | // There is not a simple way of getting the Thread ID (tid) used by the OS |
| 182 | // given the pthread_id (thread_id) that we just got from the remote process. |
| 183 | // Turns out that the pthread id is just the address of the pthread struct |
| 184 | // that is used to create the thread in the pthread library (this fact is used |
| 185 | // by gdb and other debuggers). This struct contains the tid inside so we just |
| 186 | // need to know the offset in this struct. The struct looks like this (from |
| 187 | // glibc): |
| 188 | // |
| 189 | // struct pthread { |
| 190 | // union |
| 191 | // { |
| 192 | // tcbhead_t header; |
| 193 | // void *__padding[24]; |
| 194 | // }; |
| 195 | // list_t list; |
| 196 | // pid_t tid; |
| 197 | // ... |
| 198 | // } |
| 199 | // |
| 200 | int the_tid; |
| 201 | manager->copyObjectFromProcess((remote_addr_t)(pthread_id + tid_offset_in_pthread_struct), &the_tid); |
| 202 | |
| 203 | // To double check that this number is correct, we then check that this is one |
| 204 | // of the tids that we know. A thread id of 0 means that the thread was terminated |
| 205 | // but not joined. |
| 206 | const auto& tids = manager->Tids(); |
| 207 | if (the_tid != 0 && std::find(tids.begin(), tids.end(), the_tid) == tids.end()) { |
| 208 | throw std::runtime_error("Invalid thread ID found!"); |
| 209 | } |
| 210 | return the_tid; |
| 211 | } |
| 212 | |
| 213 | remote_addr_t |
| 214 | PyThread::getFrameAddr( |
nothing calls this directly
no test coverage detected