1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "dfx_ptrace.h" 17800b99b8Sopenharmony_ci#include <chrono> 18800b99b8Sopenharmony_ci#include <sys/ptrace.h> 19800b99b8Sopenharmony_ci#include <sys/wait.h> 20800b99b8Sopenharmony_ci#include <unistd.h> 21800b99b8Sopenharmony_ci#include "dfx_define.h" 22800b99b8Sopenharmony_ci#include "dfx_log.h" 23800b99b8Sopenharmony_ci 24800b99b8Sopenharmony_cinamespace OHOS { 25800b99b8Sopenharmony_cinamespace HiviewDFX { 26800b99b8Sopenharmony_cinamespace { 27800b99b8Sopenharmony_ci#undef LOG_DOMAIN 28800b99b8Sopenharmony_ci#undef LOG_TAG 29800b99b8Sopenharmony_ci#define LOG_DOMAIN 0xD002D11 30800b99b8Sopenharmony_ci#define LOG_TAG "DfxPtrace" 31800b99b8Sopenharmony_ci} 32800b99b8Sopenharmony_ci 33800b99b8Sopenharmony_civoid DfxPtrace::Detach(pid_t tid) 34800b99b8Sopenharmony_ci{ 35800b99b8Sopenharmony_ci if (tid > 0) { 36800b99b8Sopenharmony_ci ptrace(PTRACE_CONT, tid, 0, 0); 37800b99b8Sopenharmony_ci ptrace(PTRACE_DETACH, tid, nullptr, nullptr); 38800b99b8Sopenharmony_ci } 39800b99b8Sopenharmony_ci} 40800b99b8Sopenharmony_ci 41800b99b8Sopenharmony_cibool DfxPtrace::Attach(pid_t tid, int timeout) 42800b99b8Sopenharmony_ci{ 43800b99b8Sopenharmony_ci if (tid <= 0) { 44800b99b8Sopenharmony_ci return false; 45800b99b8Sopenharmony_ci } 46800b99b8Sopenharmony_ci 47800b99b8Sopenharmony_ci if (ptrace(PTRACE_SEIZE, tid, 0, 0) != 0) { 48800b99b8Sopenharmony_ci DFXLOGW("Failed to seize tid(%{public}d), errno=%{public}d", tid, errno); 49800b99b8Sopenharmony_ci return false; 50800b99b8Sopenharmony_ci } 51800b99b8Sopenharmony_ci 52800b99b8Sopenharmony_ci if (ptrace(PTRACE_INTERRUPT, tid, 0, 0) != 0) { 53800b99b8Sopenharmony_ci DFXLOGW("Failed to interrupt tid(%{public}d), errno=%{public}d", tid, errno); 54800b99b8Sopenharmony_ci ptrace(PTRACE_DETACH, tid, nullptr, nullptr); 55800b99b8Sopenharmony_ci return false; 56800b99b8Sopenharmony_ci } 57800b99b8Sopenharmony_ci 58800b99b8Sopenharmony_ci int64_t startTime = std::chrono::duration_cast<std::chrono::milliseconds>( 59800b99b8Sopenharmony_ci std::chrono::system_clock::now().time_since_epoch()).count(); 60800b99b8Sopenharmony_ci do { 61800b99b8Sopenharmony_ci if (waitpid(tid, nullptr, WNOHANG) > 0) { 62800b99b8Sopenharmony_ci break; 63800b99b8Sopenharmony_ci } 64800b99b8Sopenharmony_ci int64_t curTime = std::chrono::duration_cast<std::chrono::milliseconds>( 65800b99b8Sopenharmony_ci std::chrono::system_clock::now().time_since_epoch()).count(); 66800b99b8Sopenharmony_ci if (curTime - startTime > timeout) { 67800b99b8Sopenharmony_ci ptrace(PTRACE_DETACH, tid, nullptr, nullptr); 68800b99b8Sopenharmony_ci DFXLOGW("Failed to wait tid(%{public}d) attached.", tid); 69800b99b8Sopenharmony_ci return false; 70800b99b8Sopenharmony_ci } 71800b99b8Sopenharmony_ci usleep(5); // 5 : sleep 5us 72800b99b8Sopenharmony_ci } while (true); 73800b99b8Sopenharmony_ci return true; 74800b99b8Sopenharmony_ci} 75800b99b8Sopenharmony_ci} // namespace HiviewDFX 76800b99b8Sopenharmony_ci} // namespace OHOS 77