From ff3e31d2b100d8efd969b358b18e4405c49dd10d Mon Sep 17 00:00:00 2001 From: Igor Murashkin Date: Wed, 23 Oct 2013 16:40:06 -0700 Subject: camera: Collect stack traces when bad things happen, print with dumpsys Bug: 11324229 Change-Id: Ic920e170a8f5a389fc139bbf5416c0e3186c7fb6 --- services/camera/libcameraservice/Android.mk | 1 + services/camera/libcameraservice/CameraService.cpp | 5 ++ .../libcameraservice/device3/Camera3Device.cpp | 5 ++ .../camera/libcameraservice/utils/CameraTraces.cpp | 94 ++++++++++++++++++++++ .../camera/libcameraservice/utils/CameraTraces.h | 66 +++++++++++++++ 5 files changed, 171 insertions(+) create mode 100644 services/camera/libcameraservice/utils/CameraTraces.cpp create mode 100644 services/camera/libcameraservice/utils/CameraTraces.h (limited to 'services') 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& 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 #include +#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 + +#include +#include + +#include +#include + +namespace android { +namespace camera3 { + +struct CameraTracesImpl { + Mutex tracesLock; + List 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& 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 &args __attribute__((unused))) { + ALOGV("%s: fd = %d", __FUNCTION__, fd); + Mutex::Autolock al(sImpl.tracesLock); + List& 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::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 +#include +#include + +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. + * + *

Use CameraTraces::dump to print out the traces.

+ */ + static void saveTrace(); + + /** + * Prints all saved traces to the specified file descriptor. + * + *

Each line is indented by DUMP_INDENT spaces.

+ */ + static status_t dump(int fd, const Vector& 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_ -- cgit v1.1