diff options
author | Igor Murashkin <iam@google.com> | 2013-10-30 14:18:45 -0700 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2013-10-30 14:18:45 -0700 |
commit | 06b3aa2f8a431eba782aa8c8f5da19f945678983 (patch) | |
tree | 19377379c26f824694905457feb9b7a69bc80084 | |
parent | ed94a039088d2218cbc69e831f16f78db53d0c83 (diff) | |
parent | 34790c866cdc309e3779b811db43f63aa7eae7ef (diff) | |
download | frameworks_av-06b3aa2f8a431eba782aa8c8f5da19f945678983.zip frameworks_av-06b3aa2f8a431eba782aa8c8f5da19f945678983.tar.gz frameworks_av-06b3aa2f8a431eba782aa8c8f5da19f945678983.tar.bz2 |
am 34790c86: am 3ff5792a: Merge "camera: Collect stack traces when bad things happen, print with dumpsys" into klp-dev
* commit '34790c866cdc309e3779b811db43f63aa7eae7ef':
camera: Collect stack traces when bad things happen, print with dumpsys
5 files changed, 171 insertions, 0 deletions
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index d23f8b9..51ba698 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -35,6 +35,7 @@ LOCAL_SRC_FILES:= \ device3/Camera3ZslStream.cpp \ device3/StatusTracker.cpp \ gui/RingBufferConsumer.cpp \ + utils/CameraTraces.cpp \ LOCAL_SHARED_LIBRARIES:= \ libui \ diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 34a5b15..eeedfc9 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -42,6 +42,7 @@ #include "api1/Camera2Client.h" #include "api_pro/ProCamera2Client.h" #include "api2/CameraDeviceClient.h" +#include "utils/CameraTraces.h" #include "CameraDeviceFactory.h" namespace android { @@ -1219,6 +1220,10 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { if (locked) mServiceLock.unlock(); + // Dump camera traces if there were any + write(fd, "\n", 1); + camera3::CameraTraces::dump(fd, args); + // change logging level int n = args.size(); for (int i = 0; i + 1 < n; i++) { diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 6f2dc85..c320d6c 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -41,6 +41,7 @@ #include <utils/Trace.h> #include <utils/Timers.h> +#include "utils/CameraTraces.h" #include "device3/Camera3Device.h" #include "device3/Camera3OutputStream.h" #include "device3/Camera3InputStream.h" @@ -1363,6 +1364,10 @@ void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) { // But only do error state transition steps for the first error if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return; + // Save stack trace. View by dumping it later. + CameraTraces::saveTrace(); + // TODO: consider adding errorCause and client pid/procname + mErrorCause = errorCause; mRequestThread->setPaused(true); diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp new file mode 100644 index 0000000..346e15f --- /dev/null +++ b/services/camera/libcameraservice/utils/CameraTraces.cpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "CameraTraces" +#define ATRACE_TAG ATRACE_TAG_CAMERA +//#define LOG_NDEBUG 0 + +#include "utils/CameraTraces.h" +#include <utils/ProcessCallStack.h> + +#include <utils/Mutex.h> +#include <utils/List.h> + +#include <utils/Log.h> +#include <cutils/trace.h> + +namespace android { +namespace camera3 { + +struct CameraTracesImpl { + Mutex tracesLock; + List<ProcessCallStack> pcsList; +}; // class CameraTraces::Impl; + +static CameraTracesImpl gImpl; +CameraTracesImpl& CameraTraces::sImpl = gImpl; + +void CameraTraces::saveTrace() { + ALOGV("%s: begin", __FUNCTION__); + ATRACE_BEGIN("CameraTraces::saveTrace"); + Mutex::Autolock al(sImpl.tracesLock); + + List<ProcessCallStack>& pcsList = sImpl.pcsList; + + // Insert new ProcessCallStack, and immediately crawl all the threads + pcsList.push_front(ProcessCallStack()); + ProcessCallStack& pcs = *pcsList.begin(); + pcs.update(); + + if (pcsList.size() > MAX_TRACES) { + // Prune list periodically and discard oldest entry + pcsList.erase(--pcsList.end()); + } + + IF_ALOGV() { + pcs.log(LOG_TAG, ANDROID_LOG_VERBOSE); + } + + ALOGD("Process trace saved. Use dumpsys media.camera to view."); + + ATRACE_END(); +} + +status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((unused))) { + ALOGV("%s: fd = %d", __FUNCTION__, fd); + Mutex::Autolock al(sImpl.tracesLock); + List<ProcessCallStack>& pcsList = sImpl.pcsList; + + if (fd < 0) { + ALOGW("%s: Negative FD (%d)", __FUNCTION__, fd); + return BAD_VALUE; + } + + fdprintf(fd, "Camera traces (%zu):\n", pcsList.size()); + + if (pcsList.empty()) { + fdprintf(fd, " No camera traces collected.\n"); + } + + // Print newest items first + List<ProcessCallStack>::iterator it, end; + for (it = pcsList.begin(), end = pcsList.end(); it != end; ++it) { + const ProcessCallStack& pcs = *it; + pcs.dump(fd, DUMP_INDENT); + } + + return OK; +} + +}; // namespace camera3 +}; // namespace android diff --git a/services/camera/libcameraservice/utils/CameraTraces.h b/services/camera/libcameraservice/utils/CameraTraces.h new file mode 100644 index 0000000..d10dbc9 --- /dev/null +++ b/services/camera/libcameraservice/utils/CameraTraces.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_SERVERS_CAMERA_TRACES_H_ +#define ANDROID_SERVERS_CAMERA_TRACES_H_ + +#include <utils/Errors.h> +#include <utils/String16.h> +#include <utils/Vector.h> + +namespace android { +namespace camera3 { + +class CameraTracesImpl; + +// Collect a list of the process's stack traces +class CameraTraces { +public: + /** + * Save the current stack trace for each thread in the process. At most + * MAX_TRACES will be saved, after which the oldest traces will be discarded. + * + * <p>Use CameraTraces::dump to print out the traces.</p> + */ + static void saveTrace(); + + /** + * Prints all saved traces to the specified file descriptor. + * + * <p>Each line is indented by DUMP_INDENT spaces.</p> + */ + static status_t dump(int fd, const Vector<String16>& args); + +private: + enum { + // Don't collect more than 100 traces. Discard oldest. + MAX_TRACES = 100, + + // Insert 2 spaces when dumping the traces + DUMP_INDENT = 2, + }; + + CameraTraces(); + ~CameraTraces(); + CameraTraces(CameraTraces& rhs); + + static CameraTracesImpl& sImpl; +}; // class CameraTraces + +}; // namespace camera3 +}; // namespace android + +#endif // ANDROID_SERVERS_CAMERA_TRACES_H_ |