import org.tizen.dynamicanalyzer.nl.UserErrorWarningLabels;
import org.tizen.dynamicanalyzer.util.Logger;
- public enum DAResult {
- SUCCESS(0, "Success!"), ERR_EXCEPTION_OCCURRED(-1, "Excpetion occurred "),
-
- // error that is not shown to the user (3 digits) ( -100 ~ -999 )
- ERR_INVALID_VERSION(-100, "not supported version "),
- ERR_REMOTE_PORT_GET_FAILED(-101, "remote port get failed!!"),
- ERR_CONTROL_SOCKET_CREATION_FAIL(-102, "control socket creation is failed "),
- ERR_DATA_SOCKET_CREATION_FAIL(-103, "data socket creation is failed "),
- ERR_CONTROL_SOCKET_CONNECTION_CLOSED(-902, "connection closed"),
- ERR_FILE_IS_NOT_EXISTS(-201, "File is not exist!"),
- ERR_UPLOAD_FILE_FAILED(-202, "file upload is failed!"),
- ERR_SDB_PUSH_FAILED(-203, "sdb push returns null"),
- ERR_READELF_SIZE_GET_FAILED(-204, "readelf size get failed"),
- ERR_READELF_UPLOAD_FAILED(-205, "readelf file size is different!!"),
- ERR_MSG_STOP_FAIL(-502, "stop message is not ok"),
- ERR_MSG_RUNTIME_FAIL(-503, "runtime message is not ok"),
- ERR_TARGET_INFO_GET_FAIL(-505, "target info get fail..."),
- ERR_KEEP_ALIVE(-506, "keep alive message ack fail..."),
- ERR_BIN_INFO_GET_FAIL(-507, "binary info get fail..."),
- ERR_RECEIVE_ACK_FAIL(-508, "receiving ack message fail..."),
- ERR_DA_IS_EXIT(-901, "Dynamic Analyzer is closing"),
-
- // error that is shown to the user (4 digits) ( -1000 ~ -9999 )
- ERR_OUT_OF_MEMORY(-1001, UserErrorWarningLabels.ERROR_OUT_OF_MEMORY),
- ERR_NO_DEVICE(-1010, UserErrorWarningLabels.ERROR_DEVICE_NOT_FOUND),
- ERR_DISCONNECTED(-1011, UserErrorWarningLabels.ERROR_DEVICE_CONNECTION),
- ERR_NO_APP(-1020, UserErrorWarningLabels.ERROR_NONEXIST_APPLICATION),
- ERR_INVALID_APP(-1021, UserErrorWarningLabels.ERROR_UNSUPPORTED_APPLICATION),
- ERR_BY_SECURITY(-1030, UserErrorWarningLabels.ERROR_BY_SECURITY_REASON),
- ERR_BY_USER_CANCEL(-1031, UserErrorWarningLabels.WARNING_USER_CANCEL),
- ERR_CONFIG_FAILED(-1100, UserErrorWarningLabels.ERROR_CONFIGURATION_FAILED),
- ERR_LIB_NOTFOUND_INRPM(-1101, UserErrorWarningLabels.ERROR_LIB_NOT_FOUND_INRPM),
- ERR_RPM_NOTFOUND(-1102, UserErrorWarningLabels.ERROR_RPM_NOT_FOUND),
- ERR_START_DATA_CHANNEL(-2001, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_START_MESSAGE_PARSER(-2002, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_START_LOG_PARSER(-2003, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_STOP_DATA_CHANNEL(-2004, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_STOP_MESSAGE_PARSER(-2005, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_STOP_LOG_PARSER(-2006, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_MSG_START_FAIL(-2007, UserErrorWarningLabels.ERROR_START_TRACE_FAILED),
- ERR_MSG_SEND_FAIL(-2008, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_NO_PROCINFO(-2009, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_CONTINUITY_BROKEN(-2010, UserErrorWarningLabels.WARNING_OVERHEAD_EXPLODE),
- ERR_WRONG_MESSAGE_FORMAT(-2011, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
- ERR_DATA_SOCKET_CLOSED(-2012, UserErrorWarningLabels.ERROR_CONNECTION_CLOSED),
- ERR_UNKNOWN(-9999, UserErrorWarningLabels.ERROR_BY_UNKNOWN_REASON);
-
- private final int errNo;
- private final String errMsg;
+ public class DAResult {
+ public enum ErrorCode {
+ SUCCESS(0, "Success!"),
+ ERR_EXCEPTION_OCCURRED(-1, "Excpetion is occurred "),
+
+ // error that is not shown to the user (3 digits) ( -100 ~ -999 )
+ ERR_INVALID_VERSION(-100, "not supported version"),
+ ERR_REMOTE_PORT_GET_FAILED(-101, "remote port get failed!!"),
+ ERR_CONTROL_SOCKET_CREATION_FAIL(-102, "control socket creation is failed"),
+ ERR_DATA_SOCKET_CREATION_FAIL(-103, "data socket creation is failed"),
+ ERR_CONTROL_SOCKET_CONNECTION_CLOSED(-104, "connection closed"),
+ ERR_PROTOCOL_NOT_SUPPORTED(-105, "procotol is not supported"),
+ ERR_FILE_IS_NOT_EXISTS(-201, "File is not exist!"),
+ ERR_UPLOAD_FILE_FAILED(-202, "file upload is failed!"),
+ ERR_SDB_PUSH_FAILED(-203, "sdb push returns null"),
+ ERR_READELF_SIZE_GET_FAILED(-204, "readelf size get failed"),
+ ERR_READELF_UPLOAD_FAILED(-205, "readelf file size is different!!"),
+ ERR_MSG_STOP_FAIL(-502, "stop message is not ok"),
+ ERR_MSG_RUNTIME_FAIL(-503, "runtime message is not ok"),
+ ERR_TARGET_INFO_GET_FAIL(-505, "target info get fail..."),
+ ERR_KEEP_ALIVE(-506, "keep alive message ack fail..."),
+ ERR_RECEIVE_ACK_FAIL(-508, "receiving ack message fail..."),
+ ERR_PROCESS_ADD_INFO_GET_FAIL(-509, "failed to get process add info..."),
+ ERR_SWAP_INSTRUMENTATION_FAIL(-510, "failed to instrument..."),
+ ERR_DA_IS_EXIT(-901, "Dynamic Analyzer is closing"),
+
+ // error that is shown to the user (4 digits) ( -1000 ~ -9999 )
+ ERR_OUT_OF_MEMORY(-1001, UserErrorWarningLabels.ERROR_OUT_OF_MEMORY),
+ ERR_NO_DEVICE(-1010, UserErrorWarningLabels.ERROR_DEVICE_NOT_FOUND),
+ ERR_DISCONNECTED(-1011, UserErrorWarningLabels.ERROR_DEVICE_CONNECTION),
+ ERR_NO_APP(-1020, UserErrorWarningLabels.ERROR_NONEXIST_APPLICATION),
+ ERR_INVALID_APP(-1021, UserErrorWarningLabels.ERROR_UNSUPPORTED_APPLICATION),
+ ERR_BY_SECURITY(-1030, UserErrorWarningLabels.ERROR_BY_SECURITY_REASON),
+ ERR_BY_USER_CANCEL(-1031, UserErrorWarningLabels.WARNING_USER_CANCEL),
+ ERR_CONFIG_FAILED(-1100, UserErrorWarningLabels.ERROR_CONFIGURATION_FAILED),
+ ERR_LIB_NOTFOUND_INRPM(-1101, UserErrorWarningLabels.ERROR_LIB_NOT_FOUND_INRPM),
+ ERR_RPM_NOTFOUND(-1102, UserErrorWarningLabels.ERROR_RPM_NOT_FOUND),
+ ERR_START_DATA_CHANNEL(-2001, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_START_MESSAGE_PARSER(-2002, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_START_LOG_PARSER(-2003, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_STOP_DATA_CHANNEL(-2004, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_STOP_MESSAGE_PARSER(-2005, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_STOP_LOG_PARSER(-2006, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
++ ERR_NO_PROCINFO(-2007, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_CONTINUITY_BROKEN(-2010, UserErrorWarningLabels.WARNING_OVERHEAD_EXPLODE),
+ ERR_WRONG_MESSAGE_FORMAT(-2011, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_DATA_SOCKET_CLOSED(-2012, UserErrorWarningLabels.ERROR_CONNECTION_CLOSED),
+ ERR_DOWNLOAD_FILE_FAILED(-2013, UserErrorWarningLabels.ERROR_DOWNLOAD_FILE_FAILED),
+
+ ERR_MSG_START_FAIL(-2101, UserErrorWarningLabels.ERROR_START_TRACE_FAILED),
+ ERR_MSG_SEND_FAIL(-2102, UserErrorWarningLabels.ERROR_INTERNAL_REASON),
+ ERR_BIN_INFO_GET_FAIL(-2103, UserErrorWarningLabels.ERROR_FAILED_OPERATION),
+ ERR_SCREENSHOT_GET_FAIL(-2104, UserErrorWarningLabels.ERROR_SCREENSHOT_FAILED),
+
+ ERR_UNKNOWN(-9999, UserErrorWarningLabels.ERROR_BY_UNKNOWN_REASON);
+
+ private final int errNumber;
+ private final String errMessage;
+
+ private ErrorCode(int num, String msg) {
+ this.errNumber = num;
+ this.errMessage = msg;
+ }
+
+ public int getErrorNumber() {
+ return this.errNumber;
+ }
+
+ public String getErrorMessage() {
+ return this.errMessage;
+ }
+ }
+
+ private ErrorCode errCode;
private String detailMsg;
- private DAResult(int num, String msg) {
- errNo = num;
- errMsg = msg;
- detailMsg = null;
+ public DAResult(ErrorCode code) {
+ this.errCode = code;
+ this.detailMsg = null;
+ }
+
+ public DAResult(ErrorCode code, String msg) {
+ this.errCode = code;
+ this.detailMsg = msg;
}
public int getErrorNumber() {
--- /dev/null
- dataSock.setSoTimeout(AnalyzerConstants.DATA_SOCKET_TIMEOUT_NORMAL);
+ /*
+ * Dynamic Analyzer
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jaewon Lim <jaewon81.lim@samsung.com>
+ * Woojin Jung <woojin2.jung@samsung.com>
+ *
+ * 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.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+ package org.tizen.dynamicanalyzer.protocol.p30;
+
+ import static org.tizen.dynamicanalyzer.constant.CommonConstants.INT_SIZE;
+
+ import java.io.BufferedReader;
+ import java.io.File;
+ import java.io.IOException;
+ import java.io.InputStreamReader;
+ import java.net.Socket;
+ import java.net.SocketException;
+ import java.net.UnknownHostException;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.TreeMap;
+ import java.util.regex.Pattern;
+
+ import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
+ import org.tizen.dynamicanalyzer.common.AnalyzerManager;
+ import org.tizen.dynamicanalyzer.common.AnalyzerShellCommands;
+ import org.tizen.dynamicanalyzer.common.DAResult;
+ import org.tizen.dynamicanalyzer.common.DAResult.ErrorCode;
+ import org.tizen.dynamicanalyzer.common.ElfSymbolExtractor;
+ import org.tizen.dynamicanalyzer.common.Global;
+ import org.tizen.dynamicanalyzer.common.path.PathManager;
+ import org.tizen.dynamicanalyzer.communicator.AckMessage;
+ import org.tizen.dynamicanalyzer.communicator.BaseCommunicator;
+ import org.tizen.dynamicanalyzer.communicator.CommunicatorUtils;
+ import org.tizen.dynamicanalyzer.communicator.DeviceInfo;
+ import org.tizen.dynamicanalyzer.communicator.ISerializable;
+ import org.tizen.dynamicanalyzer.communicator.ProcessAdditionalInfo;
+ import org.tizen.dynamicanalyzer.communicator.ProtocolParser;
+ import org.tizen.dynamicanalyzer.communicator.ProtocolSerializer;
+ import org.tizen.dynamicanalyzer.communicator.SubCommunicator;
+ import org.tizen.dynamicanalyzer.communicator.UnsupportedProtocolException;
+ import org.tizen.dynamicanalyzer.constant.CommonConstants;
+ import org.tizen.dynamicanalyzer.control.ApplistManager;
+ import org.tizen.dynamicanalyzer.control.IProgress;
+ import org.tizen.dynamicanalyzer.handlers.ReplayManager;
+ import org.tizen.dynamicanalyzer.model.AddrSymbolPair;
+ import org.tizen.dynamicanalyzer.model.DATime;
+ import org.tizen.dynamicanalyzer.nl.UserErrorWarningLabels;
+ import org.tizen.dynamicanalyzer.project.AppInfo;
+ import org.tizen.dynamicanalyzer.project.BinaryInfo;
+ import org.tizen.dynamicanalyzer.project.DeviceStatusInfo;
+ import org.tizen.dynamicanalyzer.project.PackageInfo;
+ import org.tizen.dynamicanalyzer.setting.Feature;
+ import org.tizen.dynamicanalyzer.setting.SettingDataManager;
+ import org.tizen.dynamicanalyzer.setting.TargetData;
+ import org.tizen.dynamicanalyzer.swap.communicator.SwapErrorCode;
+ import org.tizen.dynamicanalyzer.swap.model.data.RecordEventObject;
+ import org.tizen.dynamicanalyzer.swap.model.data.ReplayData;
+ import org.tizen.dynamicanalyzer.ui.toolbar.replay.data.ReplayDataManager;
+ import org.tizen.dynamicanalyzer.util.ByteUtil;
+ import org.tizen.dynamicanalyzer.util.CommonUtil;
+ import org.tizen.dynamicanalyzer.util.Logger;
+ import org.tizen.sdblib.receiver.MultiLineReceiver;
+ import org.tizen.sdblib.service.SyncResult;
+
+ public class Communicator30 extends SubCommunicator {
+ private Socket dataSocket = null;
+
+ public Communicator30(BaseCommunicator parent) {
+ super(parent);
+ }
+
+ @Override
+ public Socket getDataSocket(int index) {
+ return dataSocket;
+ }
+
+ @Override
+ public DAResult connect() {
+ DAResult result;
+
+ int localPort = parent.getLocalPort();
+
+ result = createDataSocket(localPort);
+ if (!result.isSuccess()) {
+ Logger.warning(result.toString());
+ return new DAResult(ErrorCode.ERR_DATA_SOCKET_CREATION_FAIL);
+ }
+
+ // get target information
+ result = sendTargetInfoMessage(null);
+ if (!result.isSuccess()) {
+ Logger.warning(result.toString());
+ return result;
+ }
+
+ // get api map information
+ parent.getDevice().getDeviceStatusInfo().setApiNameMap(getApiMap());
+
+ // send configuration message
+ result = sendConfigurationMessage(null);
+ if (result.isSuccess()) {
+ parent.getDevice().setConfigSuccess(true);
+ } else {
+ Logger.warning(result.toString());
+ }
+
+ return result;
+ }
+
+ @Override
+ public DAResult disconnect() {
+ if (dataSocket != null) {
+ try {
+ dataSocket.close();
+ } catch (IOException e) {
+ Logger.warning("Failed to close data socket");
+ }
+ }
+
+ return new DAResult(ErrorCode.SUCCESS);
+ }
+
+ protected DAResult createDataSocket(int localPort) {
+ DAResult result = new DAResult(ErrorCode.SUCCESS);
+ Socket dataSock = null;
+ try {
+ dataSock = new Socket(CommonConstants.LOCAL_HOST, localPort);
++ dataSock.setSoTimeout(AnalyzerConstants.DATA_SOCKET_INTERRUPT_INTERVAL);
+ dataSock.setReuseAddress(true);
+ dataSock.setTcpNoDelay(true);
+ } catch (UnknownHostException e) {
+ result = new DAResult(ErrorCode.ERR_EXCEPTION_OCCURRED);
+ result.setDetailMessage(e.getMessage());
+ Logger.exception(e);
+ } catch (SocketException e) {
+ result = new DAResult(ErrorCode.ERR_EXCEPTION_OCCURRED);
+ result.setDetailMessage(e.getMessage());
+ Logger.exception(e);
+ } catch (IOException e) {
+ result = new DAResult(ErrorCode.ERR_EXCEPTION_OCCURRED);
+ result.setDetailMessage(e.getMessage());
+ Logger.exception(e);
+ }
+
+ if (result.isSuccess()) {
+ dataSocket = dataSock;
+ AnalyzerManager.setDataSocketClosed(false);
+ }
+
+ return result;
+ }
+
+ @Override
+ public DAResult sendTargetInfoMessage(IProgress progress) {
+ Logger.debug("Send target info...");
+
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_TARGET_INFO);
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+ if (result != null && result.isSuccess()
+ && result.isCorrectID(ProtocolConstant30.MSG_TARGET_INFO_ACK)) {
+ byte[] pbyte = result.getPayload();
+ if (pbyte != null) {
+ ProtocolParser parser = new ProtocolParser(pbyte);
+ DeviceStatusInfo tInfo = parent.getDevice().getDeviceStatusInfo();
+
+ parser.getInt(); // for return code
+
+ tInfo.setSystemMemorySize(parser.getLong());
+ tInfo.setStorageSize(parser.getLong());
+ tInfo.setBluetoothSupport(parser.getInt());
+ tInfo.setGpsSupport(parser.getInt());
+ tInfo.setWifiSupport(parser.getInt());
+ tInfo.setCameraCount(parser.getInt());
+ tInfo.setNetworkType(parser.getString());
+ tInfo.setMaxBrightness(parser.getInt());
+ tInfo.setCpuCount(parser.getInt());
+
+ int numberOfDevice = parser.getInt();
+ tInfo.setDeviceCount(numberOfDevice);
+
+ String deviceList = CommonConstants.EMPTY;
+ for (int i = 0; i < numberOfDevice; i++) {
+ deviceList += parser.getString();
+ if (i + 1 != numberOfDevice) {
+ deviceList += CommonConstants.COMMA;
+ }
+ }
+ tInfo.setDevices(deviceList);
+
+ return new DAResult(ErrorCode.SUCCESS);
+ }
+ }
+
+ return new DAResult(ErrorCode.ERR_TARGET_INFO_GET_FAIL);
+ }
+
+ protected Map<Integer, String> getApiMap() {
+ DeviceInfo device = parent.getDevice();
+ final List<String> lines = new ArrayList<String>();
+
+ CommunicatorUtils.execShellCommand(device.getIDevice(),
+ AnalyzerShellCommands.DACOMMAND_GETAPI, new MultiLineReceiver() {
+ @Override
+ public void processNewLines(String[] newlines) {
+ for (int i = 0; i < newlines.length; i++) {
+ lines.add(newlines[i]);
+ }
+ }
+ });
+
+ Map<Integer, String> apiMap = new TreeMap<Integer, String>();
+ apiMap.put(Integer.valueOf(0), AnalyzerConstants.UNKNOWN_API);
+
+ if (lines.size() > 0) {
+ if (!lines.get(0).contains(AnalyzerConstants.CMDSCRIPT_UNKNOWN)
+ && !lines.get(0).contains(AnalyzerConstants.CMDSCRIPT_USAGE)) {
+ for (int i = 0; i < lines.size(); i++) {
+ String input = lines.get(i);
+ String[] splitLine = input.trim().split(CommonConstants.SPACE, 2);
+ if (splitLine.length > 1) {
+ int index = Integer.parseInt(splitLine[0]);
+ apiMap.put(Integer.valueOf(index), splitLine[1]);
+ } else {
+ Logger.debug("api map parsing is wrong");
+ }
+ }
+ }
+ }
+
+ return apiMap;
+ }
+
+ @Override
+ public DAResult sendConfigurationMessage(IProgress progress) {
+ // send config message
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_CONFIG);
+
+ // set feature flag value
+ Set<Feature> selectedFeatures = SettingDataManager.INSTANCE.getSelectedFeatureSet();
+ byte[] featureFlag = ProtocolConfig30.getFeatureFlagValue(selectedFeatures);
+ ps.putByteArray(featureFlag);
+
+ // set sampling period value
+ TargetData target = SettingDataManager.INSTANCE.getConnectedTarget();
+ int systemPeriod = target.getSelectedFeatureValue(Feature.SYSTEM_SAMPLING_RATE);
+ if (systemPeriod < 0) {
+ systemPeriod = Feature.SYSTEM_SAMPLING_RATE.getData().getDefaultValue();
+ }
+ int samplingPeriod = target.getSelectedFeatureValue(Feature.FUNCTION_SAMPLING_RATE);
+ if (samplingPeriod < 0) {
+ samplingPeriod = Feature.FUNCTION_SAMPLING_RATE.getData().getDefaultValue();
+ }
+ ps.putInt(systemPeriod);
+ ps.putInt(samplingPeriod);
+
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+
+ if (result != null && result.isSuccess()
+ && result.isCorrectID(ProtocolConstant30.MSG_CONFIG_ACK)) {
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_CONFIG_FAILED);
+ }
+ }
+
+ @Override
+ public DAResult sendTraceStartMessage(IProgress progress) throws InterruptedException {
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_START_SWAP);
+
+ // serialize application inst.
+ if (!serializeApplicationInst(ps)) {
+ Logger.error("cannot get application inst");
+ return new DAResult(ErrorCode.ERR_MSG_START_FAIL);
+ }
+
+ // serialize the replay data
+ serializeReplayEvent(ps);
+
+ byte[] msg = ps.toByteArray();
+
+ // start message send
+ AckMessage result = parent.handleControlMessage(msg);
+ if (result != null && result.isCorrectID(ProtocolConstant30.MSG_START_ACK)
+ && result.isSuccess()) {
+ ProtocolParser pp = new ProtocolParser(result.getPayload());
+ pp.getInt(); // for return code
+
+ int sec = pp.getInt();
+ int nano = pp.getInt();
+ synchronized (AnalyzerManager.waitStartAck) {
+ Global.getProject().setProfilingStartTime(new DATime(sec, nano));
+ AnalyzerManager.waitStartAck.notifyAll();
+ }
+
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_MSG_START_FAIL);
+ }
+ }
+
+ // return false if there is no application inst.
+ // return true, otherwise
+ protected boolean serializeApplicationInst(ProtocolSerializer ps) {
+ DeviceInfo dev = parent.getDevice();
+ String pkgID = Global.getCurrentApplication().getPackageId();
+ PackageInfo pkgInfo = dev.getPkgInfoByPkgID(pkgID);
+ List<AppInfo> apps = pkgInfo.getAppInfos();
+
+ List<ISerializable> appInstList = new ArrayList<ISerializable>();
+
+ if (pkgInfo.getPackageId().equals(AnalyzerConstants.RUNNING_PROCESS)) {
+ // if running process is selected for tracing
+ Map<Integer, String> selectedProcess = apps.get(0).getRunningProcesses();
+ if (selectedProcess != null && selectedProcess.size() > 0) {
+ for (Map.Entry<Integer, String> entry : selectedProcess.entrySet()) {
+ BinaryInfo binInfo = Global.getProject().getDeviceStatusInfo()
+ .getBinaryInfo(entry.getValue());
+ String temppath = binInfo.getTempBinaryPath();
+ if (temppath == null) {
+ // this means the app binary does not exist in device
+ continue;
+ }
+
+ ApplicationInst30 appInst = new ApplicationInst30();
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_PROCESS);
+ appInst.setApplicationID(entry.getKey().toString());
+ appInst.setExecutablePath(entry.getValue());
+
+ List<AddrSymbolPair> symbols = apps.get(0).getSymbols(temppath);
+ appInst.setFunctionInstList(getFunctionInstList(symbols));
+
+ appInstList.add(appInst);
+ }
+ }
+ } else if (pkgInfo.getPackageId().equals(AnalyzerConstants.WITHOUT_EXECUTABLE)) {
+ // if no executable is selected for tracing (system wide tracing)
+ ApplicationInst30 appInst = new ApplicationInst30();
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_PROCESS);
+ appInst.setApplicationID(CommonConstants.EMPTY);
+ appInst.setExecutablePath(CommonConstants.EMPTY);
+
+ appInstList.add(appInst);
+ } else { // normal application or common executable is selected
+ for (int k = 0; k < apps.size(); k++) {
+ AppInfo app = apps.get(k);
+
+ // check if application is in black list
+ if (ApplistManager.isInBlackList(app)) {
+ continue;
+ }
+
+ BinaryInfo binInfo = Global.getProject().getDeviceStatusInfo()
+ .getBinaryInfo(app.getExecBinaryPath());
+ String temppath = binInfo.getTempBinaryPath();
+ if (temppath == null) {
+ // this means the app binary does not exist in device
+ continue;
+ }
+
+ List<AddrSymbolPair> symbols = app.getSymbols(temppath);
+ List<ISerializable> functionInstList = getFunctionInstList(symbols);
+ if (functionInstList.isEmpty()) {
+ // this means there is no function inst.
+ continue;
+ }
+
+ ApplicationInst30 appInst = new ApplicationInst30();
+
+ // TODO : make sure that first app of package is main app
+ if (k == 0) {
+ String appType = app.getInfo(AppInfo.PROPERTY.APPTYPE.index);
+ if (appType.contains(AppInfo.APPTYPE_CPP)) {
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_TIZEN);
+ appInst.setApplicationID(app.getAppID());
+ } else if (appType.contains(AppInfo.APPTYPE_WEB)) {
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_WEB);
+ appInst.setApplicationID(app.getAppID());
+ } else if (appType.contains(AppInfo.APPTYPE_CAPP)) {
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_TIZEN);
+ appInst.setApplicationID(app.getAppID());
+ } else {
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_COMMON_EXEC);
+ appInst.setApplicationID(CommonConstants.EMPTY);
+ }
+ } else {
+ appInst.setApplicationType(ProtocolConstant30.APPTYPE_PROCESS);
+ appInst.setApplicationID(CommonConstants.EMPTY);
+ }
+
+ appInst.setExecutablePath(app.getExecPath());
+ appInst.setFunctionInstList(functionInstList);
+
+ appInstList.add(appInst);
+ }
+ }
+
+ // put application inst. count
+ ps.putInt(appInstList.size());
+
+ // serialize application inst. by ProtocolSerializer
+ for (ISerializable appInst : appInstList) {
+ appInst.serialize(ps);
+ }
+
+ if (appInstList.size() == 0) {
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ protected List<ISerializable> getFunctionInstList(List<AddrSymbolPair> symbols) {
+ List<ISerializable> functionInstList = new ArrayList<ISerializable>();
+
+ int size = (symbols == null) ? 0 : symbols.size();
+ for (int i = 0; i < size; i++) {
+ AddrSymbolPair addrSymbol = symbols.get(i);
+ String symbol = addrSymbol.getSymbol();
+
+ if (ProtocolFilter30.isInBlacklistFunctionInst(symbol)) {
+ continue;
+ }
+
+ FunctionInst30 functionInst = new FunctionInst30();
+ functionInst.setAddr(addrSymbol.getAddr());
+ functionInst.setArgs(getFunctionArgs(symbol));
+ functionInstList.add(functionInst);
+ }
+
+ return functionInstList;
+ }
+
+ protected boolean serializeReplayEvent(ProtocolSerializer ps) {
+ // make replay event
+ // on/off, replay start time, count, event objects
+ if (ReplayManager.isReplayMode()) {
+ ps.putInt(ProtocolConstant30.REPLAY_ON);
+
+ DATime replayStartTime = ReplayManager.getStartTime();
+ ps.putInt(replayStartTime.getSec());
+ ps.putInt(replayStartTime.getNano());
+
+ ReplayData replayData = ReplayDataManager.getInstance().getReplayDBManager()
+ .getReplayLogs();
+ if (null != replayData) {
+ List<RecordEventObject> recordEventList = replayData.getRecordEvent();
+ int eventCount = recordEventList.size();
+ ps.putInt(eventCount);
+ for (int i = 0; i < eventCount; i++) {
+ RecordEventObject event = recordEventList.get(i);
+ ps.putInt(event.getEventTime().getSec());
+ ps.putInt(event.getEventTime().getNano());
+ ps.putInt(event.getEventId());
+ ps.putInt(event.getEventType());
+ ps.putInt(event.getEventCode());
+ ps.putInt(event.getEventValue());
+ }
+ } else {
+ ps.putInt(0); // count of replay event
+ }
+ } else {
+ ps.putInt(ProtocolConstant30.REPLAY_OFF);
+ }
+
+ return true;
+ }
+
+ @Override
+ public DAResult sendTraceStopMessage(IProgress progress) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_STOP_SWAP);
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+ if (result != null && result.isSuccess()
+ && result.isCorrectID(ProtocolConstant30.MSG_STOP_ACK)) {
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_MSG_STOP_FAIL);
+ }
+ }
+
+ @Override
+ public DAResult sendInstrumentAddMessage(IProgress progress, List<String> paths) {
+ return sendIntrumentMessage(true, paths);
+ }
+
+ @Override
+ public DAResult sendInstrumentRemoveMessage(IProgress progress, List<String> paths) {
+ return sendIntrumentMessage(false, paths);
+ }
+
+ protected DAResult sendIntrumentMessage(boolean isAdd, List<String> paths) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+
+ if (isAdd) {
+ ps.setMessageID(ProtocolConstant30.MSG_SWAP_INST_ADD);
+ } else {
+ ps.setMessageID(ProtocolConstant30.MSG_SWAP_INST_REMOVE);
+ }
+
+ DeviceInfo dev = parent.getDevice();
+
+ List<ISerializable> libInstList = new ArrayList<ISerializable>();
+
+ int count = paths.size();
+ for (int a = 0; a < count; a++) {
+ String binaryPath = paths.get(a);
+ BinaryInfo binInfo = dev.getDeviceStatusInfo().getBinaryInfo(binaryPath);
+ if (null == binInfo) {
+ continue;
+ }
+ String localPath = binInfo.getTempBinaryPath();
+
+ ElfSymbolExtractor symbolExtractor = new ElfSymbolExtractor();
+ if (!symbolExtractor.makeSymbol(localPath)) {
+ continue;
+ }
+ List<AddrSymbolPair> symbols = symbolExtractor.getAddrSymbolPairs();
+
+ List<ISerializable> functionInstList = getFunctionInstList(symbols);
+
+ LibraryInst30 newInst = new LibraryInst30();
+ newInst.setPath(binaryPath);
+ newInst.setFunctionInstList(functionInstList);
+ libInstList.add(newInst);
+ }
+
+ if (libInstList.isEmpty()) {
+ Logger.warning("Failed to send instrumentation : there is no available binary");
+ return new DAResult(ErrorCode.ERR_SWAP_INSTRUMENTATION_FAIL);
+ }
+
+ // serialize library inst. count
+ ps.putInt(libInstList.size());
+
+ // serialize library inst.
+ for (ISerializable libInst : libInstList) {
+ libInst.serialize(ps);
+ }
+
+ // get message byte from ProtocolSerializer
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+
+ int ackMsg;
+ if (isAdd) {
+ ackMsg = ProtocolConstant30.MSG_SWAP_INST_ADD_ACK;
+ } else {
+ ackMsg = ProtocolConstant30.MSG_SWAP_INST_REMOVE_ACK;
+ }
+
+ if (result != null && result.isCorrectID(ackMsg) && result.isSuccess()) {
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_SWAP_INSTRUMENTATION_FAIL);
+ }
+ }
+
+ @Override
+ public DAResult sendBinaryInfoMessage(IProgress progress, List<String> binPaths) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+
+ // make message
+ ps.setMessageID(ProtocolConstant30.MSG_BINARY_INFO);
+
+ int binCount = binPaths.size();
+ ps.putInt(binCount);
+
+ for (int i = 0; i < binCount; i++) {
+ String targetPath = binPaths.get(i);
+ ps.putString(targetPath);
+ }
+
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+ if (result != null && result.isCorrectID(ProtocolConstant30.MSG_BINARY_INFO_ACK)) {
+ if (result.isSuccess()
+ || (result.getReturnCode() == SwapErrorCode.ERR_WRONG_MESSAGE_DATA
+ .getErrorNumber() && result.getPayloadLength() > INT_SIZE)) {
+ // some binary information may not be available, but that of the others is obtained
+
+ // parse binary info
+ return parseBinaryInfo(result.getPayload(), binPaths);
+ }
+ }
+
+ return new DAResult(ErrorCode.ERR_BIN_INFO_GET_FAIL);
+ }
+
+ protected DAResult parseBinaryInfo(byte[] payload, List<String> targetPaths) {
+ DAResult ret = new DAResult(ErrorCode.SUCCESS);
+ StringBuffer detailErrorMsg = new StringBuffer();
+
+ ProtocolParser parser = new ProtocolParser(payload);
+ parser.getInt(); // for return code
+
+ DeviceInfo curDevice = parent.getDevice();
+
+ int count = parser.getInt();
+ for (int i = 0; i < count; i++) {
+ String targetPath = targetPaths.get(i);
+ BinaryInfo binInfo = curDevice.getDeviceStatusInfo().getBinaryInfo(targetPath);
+
+ int binaryType = parser.getInt();
+ String localBinaryPath = parser.getString().trim();
+ String md5sum = parser.getString();
+
+ binInfo.setType(binaryType);
+ binInfo.setMd5sumValue(md5sum);
+ binInfo.setTempBinaryPath(null);
+
+ if (binaryType < 0) {
+ // binary does not exist in target(-1) or is non-elf binary(-2)
+ // so do not try to download binary from target
+ if (detailErrorMsg.length() != 0) {
+ detailErrorMsg.append("\n");
+ }
+
+ if (binaryType == ProtocolConstant30.BINTYPE_NOT_EXIST) {
+ detailErrorMsg.append(UserErrorWarningLabels.ERROR_NONEXIST_BINARY + "("
+ + targetPath + ")");
+ } else if (binaryType == ProtocolConstant30.BINTYPE_NOT_ELF) {
+ detailErrorMsg.append(UserErrorWarningLabels.ERROR_NONELF_BINARY + "("
+ + targetPath + ")");
+ }
+
+ ret = new DAResult(ErrorCode.ERR_BIN_INFO_GET_FAIL);
+ continue;
+ }
+
+ DAResult result = checkDirtyOfBinary(binInfo, localBinaryPath);
+ if (!result.isSuccess()) {
+ if (detailErrorMsg.length() != 0) {
+ detailErrorMsg.append("\n");
+ }
+ detailErrorMsg.append(result.getMessage());
+
+ ret = new DAResult(ErrorCode.ERR_BIN_INFO_GET_FAIL);
+ }
+ }
+
+ if (!ret.isSuccess()) {
+ ret.setDetailMessage(detailErrorMsg.toString());
+ }
+
+ return ret;
+ }
+
+ protected DAResult checkDirtyOfBinary(BinaryInfo binInfo, String localBinaryPath) {
+ DAResult result = new DAResult(ErrorCode.SUCCESS);
+ String targetPath = binInfo.getTargetBinaryPath();
+
+ String[] splitLocalBinaryPath = localBinaryPath.split(Pattern.quote(File.separator));
+
+ // check local binary path validation
+ // host has no binary file - pull binary file from target
+ if (splitLocalBinaryPath.length < 3 || !(new File(localBinaryPath)).exists()) {
+ localBinaryPath = PathManager.DA_TEMP_FOLDER_PATH + File.separator
+ + getFileName(targetPath);
+ result = pullTheFile(targetPath, localBinaryPath);
+ if (result.isSuccess()) {
+ binInfo.setTempBinaryPath(localBinaryPath);
+ }
+ } else {
+ // if local binary exist already, then check for md5sum
+ String localHashCode = null;
+ try {
+ Runtime rt = Runtime.getRuntime();
+ Process process = rt.exec(new String[] { getMd5Command(), localBinaryPath });
+ process.waitFor();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ process.getInputStream()));
+ BufferedReader error = new BufferedReader(new InputStreamReader(
+ process.getErrorStream()));
+ String line = reader.readLine();
+ String errorStr = error.readLine();
+ if (null == line) {
+ Logger.warning("host md5sum get failed : " + errorStr);
+ } else {
+ // md5sum.exe prepend "\" when target binary is not in
+ // current directory
+ if (CommonUtil.isWin()) {
+ line = line.replace("\\", "");
+ }
+ localHashCode = parseMd5Result(line);
+ }
+ } catch (IOException e) {
+ Logger.exception(e);
+ } catch (InterruptedException e) {
+ Logger.exception(e);
+ }
+
+ if (localHashCode == null || 0 != localHashCode.compareTo(binInfo.getMd5sumValue())) {
+ localBinaryPath = PathManager.DA_TEMP_FOLDER_PATH + File.separator
+ + getFileName(targetPath);
+ result = pullTheFile(targetPath, localBinaryPath);
+ if (result.isSuccess()) {
+ binInfo.setTempBinaryPath(localBinaryPath);
+ }
+ } else {
+ binInfo.setTempBinaryPath(localBinaryPath);
+ }
+ }
+
+ // result succeed if getting for any binary info succeed
+ return result;
+ }
+
+ protected DAResult pullTheFile(String from, String to) {
+ DeviceInfo curDev = parent.getDevice();
+
+ if (!CommunicatorUtils.becomeSuperUser(curDev.getIDevice())) {
+ return new DAResult(ErrorCode.ERR_BY_SECURITY);
+ }
+
+ SyncResult res = CommunicatorUtils.pull(curDev.getIDevice(), from, to);
+ if (null != res && res.isOk()) {
+ Logger.debug("binary copy success : " + from);//$NON-NLS-1$
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ Logger.debug("Failed to get " + from); //$NON-NLS-1$
+ return new DAResult(ErrorCode.ERR_DOWNLOAD_FILE_FAILED);
+ }
+ }
+
+ protected String getMd5Command() {
+ String cmd = null;
+
+ if (CommonUtil.isLinux()) {
+ cmd = AnalyzerShellCommands.CMD_LINUX_MD_5_SUM;
+ } else if (CommonUtil.isMac()) {
+ cmd = AnalyzerShellCommands.CMD_MAC_MD_5_SUM;
+ } else if (CommonUtil.isWin()) {
+ cmd = PathManager.DA_TOOL_FOLDER_PATH + File.separator
+ + AnalyzerShellCommands.CMD_WIN_MD_5_SUM;
+ } else { // should never be here
+ Logger.warning("Unknown host OS!\n");
+ }
+
+ return cmd;
+ }
+
+ protected String parseMd5Result(String line) {
+ String md5value = null;
+ String[] splitResult = line.trim().split(CommonConstants.SPACE);
+
+ if (CommonUtil.isLinux()) {
+ md5value = new String(splitResult[0]);
+ } else if (CommonUtil.isMac()) { // In md5's output, hash value comes last
+ md5value = new String(splitResult[splitResult.length - 1]);
+ } else if (CommonUtil.isWin()) {
+ md5value = new String(splitResult[0]);
+ } else { // should never be here
+ Logger.warning("Unknown host OS!\n");
+ }
+
+ return md5value;
+ }
+
+ protected String getFileName(String fullPath) {
+ if (null == fullPath || fullPath.isEmpty()) {
+ return null;
+ }
+ String[] splitPath = fullPath.split(CommonConstants.SLASH);
+ return new String(splitPath[splitPath.length - 1]);
+ }
+
+ @Override
+ public DAResult sendKeepAliveMessage(IProgress progress) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_KEEP_ALIVE);
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg);
+ if (result != null && result.isCorrectID(ProtocolConstant30.MSG_KEEP_ALIVE_ACK)
+ && result.isSuccess()) {
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_KEEP_ALIVE);
+ }
+ }
+
+ // FIXME: this method works on c++ only
+ protected byte[] getFunctionArgs(String symbol) {
+ int start = symbol.indexOf(CommonConstants.OPEN_BRACKET);
+ int end = symbol.indexOf(CommonConstants.CLOSE_BRACKET);
+
+ byte[] emptyRet = new byte[] { 'p', 0, 'n' };
+
+ if (start < 0 || end < 0) {
+ return emptyRet;
+ }
+
+ String argStr = symbol.substring(start + 1, end).trim();
+ if (argStr.isEmpty()) {
+ return emptyRet;
+ }
+
+ // FIXME: some function cannot be split by comma for each parameter
+ // especially some class method with template
+ // ex) std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>
+ // >::insert(__gnu_cxx::__normal_iterator<wchar_t*, std::basic_string<wchar_t,
+ // std::char_traits<wchar_t>, std::allocator<wchar_t> > >, wchar_t)
+ String[] args = argStr.split(CommonConstants.COMMA);
+ byte[] ret = new byte[args.length + 2];
+ ret[args.length + 1] = 0;
+ ret[0] = 'p';
+ for (int i = 0; i < args.length; i++) {
+ String arg = args[i];
+ int index = arg.indexOf(CommonConstants.SPACE);
+ if (index > 0) {
+ arg = arg.substring(0, index - 1);
+ }
+
+ ret[i + 1] = (byte) getArgType(arg);
+ }
+
+ byte[] test = new byte[] { 'n' };
+ ret = ByteUtil.getByte(ret, test);
+ return ret;
+ }
+
+ protected char getArgType(String input) {
+ if (input.equals("int")) {
+ return 'd';
+ } else if (input.equals("char")) {
+ return 'c';
+ } else if (input.equals("long")) {
+ return 'x';
+ } else if (input.equals("float")) {
+ return 'f';
+ } else if (input.equals("double")) {
+ return 'w';
+ } else if (input.equals("bool")) {
+ return 'b';
+ } else {
+ return 'p';
+ }
+ }
+
+ @Override
+ public DAResult sendScreenshotMessage(IProgress progress) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_GET_SCREENSHOT);
+ byte[] msg = ps.toByteArray();
+
+ AckMessage result = parent.handleControlMessage(msg, 0, false);
+ if (result != null && result.isSuccess()) {
+ return new DAResult(ErrorCode.SUCCESS);
+ } else {
+ return new DAResult(ErrorCode.ERR_SCREENSHOT_GET_FAIL);
+ }
+ }
+
+ @Override
+ public DAResult sendProcessAddInfoMessage(IProgress progress, List<Integer> pids,
+ Map<Integer, ProcessAdditionalInfo> infoMap) {
+ infoMap.clear();
+
+ int pidcount = pids.size();
+ if (pidcount > 0) {
+ ProtocolSerializer ps = new ProtocolSerializer();
+ ps.setMessageID(ProtocolConstant30.MSG_GET_PROCESS_ADD_INFO);
+ ps.putInt(pidcount);
+
+ for (int i = 0; i < pidcount; i++) {
+ int pid = pids.get(i).intValue();
+ ps.putInt(pid);
+ }
+
+ byte[] msg = ps.toByteArray();
+ AckMessage result = parent.handleControlMessage(msg,
+ AnalyzerConstants.PROC_ADD_INFO_TIMEOUT);
+
+ if (result != null
+ && result.isCorrectID(ProtocolConstant30.MSG_GET_PROCESS_ADD_INFO_ACK)) {
+ if (result.isSuccess() || result.getPayloadLength() > INT_SIZE) {
+ // parse process additional information
+ ProtocolParser parser = new ProtocolParser(result.getPayload());
+ parser.getInt(); // for return code
+
+ int count = parser.getInt();
+ for (int i = 0; i < count; i++) {
+ int pid = parser.getInt();
+ String cmdname = parser.getString();
+ ProcessAdditionalInfo procinfo = new ProcessAdditionalInfo();
+ procinfo.setProcessName(cmdname);
+ infoMap.put(Integer.valueOf(pid), procinfo);
+ }
+ }
+ }
+ }
+
+ if (infoMap.isEmpty()) {
+ return new DAResult(ErrorCode.ERR_PROCESS_ADD_INFO_GET_FAIL);
+ } else {
+ return new DAResult(ErrorCode.SUCCESS);
+ }
+ }
+
+ @Override
+ public DAResult sendProbeMapMessage(IProgress progress) throws UnsupportedProtocolException {
+ throw new UnsupportedProtocolException();
+ }
+ }