Logger.warning("DA is not able to trace application " + appID);
return code;
}
- devInfo.setSelectedAppID(appID);
return ErrorCode.SUCCESS;
}
private static Option screenshotPeriod = Option.builder("S")
.hasArg()
.argName("period")
- .desc("Enable screenshots capturing periodically").build();
+ .desc("enable screenshots capturing periodically").build();
private static Option screenshotTransition = Option.builder("s")
- .desc("Enable screenshots capturing on scene transition")
+ .desc("enable screenshots capturing on scene transition")
.build();
private static Option lsan = Option.builder("L")
private TracingFeatureArgument(String name, PrimitiveFeature feature) {
this.option = Option.builder(name)
.longOpt(feature.getName().toLowerCase().replace(' ', '-'))
- .desc("Select " + feature.getName().toLowerCase() + " tracing")
+ .desc("select " + feature.getName().toLowerCase() + " tracing")
.build();
defFeatures.add(feature);
}
<parent>
<artifactId>dynamic-analyzer</artifactId>
<groupId>org.tizen.dynamicanalyzer</groupId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.4-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>org.tizen.dynamicanalyzer</groupId>
<parent>
<artifactId>dynamic-analyzer</artifactId>
<groupId>org.tizen.dynamicanalyzer</groupId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.4-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>org.tizen.dynamicanalyzer</groupId>
package org.tizen.dynamicanalyzer.ui.memory.data;
import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import java.io.File;
import java.io.PrintWriter;
import java.util.List;
import org.junit.After;
+import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
-import org.mockito.Mockito;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
import org.mockito.internal.util.reflection.Whitebox;
+import org.mockito.runners.MockitoJUnitRunner;
import org.powermock.reflect.internal.WhiteboxImpl;
import org.tizen.dynamicanalyzer.common.Global;
+import org.tizen.dynamicanalyzer.database.DBInserter;
import org.tizen.dynamicanalyzer.project.Project;
import org.tizen.dynamicanalyzer.swap.model.data.MemoryData;
import org.tizen.dynamicanalyzer.util.InternalLogger;
/**
* Tests for {@link HeapDataManager}.
*/
+@RunWith(MockitoJUnitRunner.class)
public class HeapDataManagerTest {
private final static String lsanReport = "lsan.test.log";
private final static String lsanReportFormat = "%d %d %d\n";
- private PrintWriter lsanReportWriter;
- private HeapDataManager manager = Mockito.spy(HeapDataManager.getInstance());
+
+ @Mock
+ private DBInserter lsanDBInserter;
+
+ @Spy
+ private HeapDataManager manager = HeapDataManager.getInstance();
@BeforeClass
public static void init() {
Logger.init(InternalLogger.DEBUG);
}
+ @Before
+ public void setUp() {
+ Whitebox.setInternalState(manager, "lsanDBInserter", lsanDBInserter);
+ }
+
/**
* Helper method for writing LSan report file and parsing it by
- * {@link HeapDataManager#parseReportFile(String)}.
+ * {@link HeapDataManager#parseLSanReportFile(String)}.
*
* @param content content of report file
- * @return list of data from parsed LSan report file
* @throws Exception
*/
- private List<List<Object>> parseReport(String content) throws Exception {
- lsanReportWriter = new PrintWriter(lsanReport, StandardCharsets.US_ASCII.name());
+ private void parseLSanReport(String content) throws Exception {
+ PrintWriter lsanReportWriter = new PrintWriter(lsanReport,
+ StandardCharsets.US_ASCII.name());
lsanReportWriter.write(content);
lsanReportWriter.flush();
lsanReportWriter.close();
- manager.parseReportFile(lsanReport);
-
- return getLSanData();
- }
-
- /**
- * Gets list of data from parsed LSan report file.
- *
- * @return value of 'lsanDataList' private field of {@link HeapDataManager}
- */
- @SuppressWarnings("unchecked")
- private List<List<Object>> getLSanData() {
- return (List<List<Object>>) Whitebox.getInternalState(manager, "lsanDataList");
+ manager.parseLSanReportFile(lsanReport);
}
@Test
- public void parseReportFile_correctFormat() throws Exception {
+ public void parseLSanReportFile_correctFormat() throws Exception {
List<List<Object>> expected = new ArrayList<List<Object>>();
StringBuffer report = new StringBuffer();
row.add(5L);
report.append(String.format(lsanReportFormat, (Long) row.get(0), (Long) row.get(1), (Long) row.get(2)));
- assertEquals(expected, parseReport(report.toString()));
+ parseLSanReport(report.toString());
+ verify(lsanDBInserter).pushData(eq(expected));
}
@Test
- public void parseReportFile_partlyCorrectFormat() throws Exception {
+ public void parseLSanReportFile_partlyCorrectFormat() throws Exception {
List<List<Object>> expected = new ArrayList<List<Object>>();
StringBuffer report = new StringBuffer();
// incorrect line
report.append("test");
- assertEquals(expected, parseReport(String.format(lsanReportFormat, 0, 1, 2) + "test"));
+ parseLSanReport(report.toString());
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
- public void parseReportFile_nonExistentReport() {
- manager.parseReportFile("non-existent/report.file");
- assertEquals(0, getLSanData().size());
+ public void parseLSanReportFile_nonExistentReport() {
+ manager.parseLSanReportFile("non-existent/report.file");
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
- public void parseReportFile_nonDigits() throws Exception {
- List<List<Object>> data = parseReport("a b c");
- assertEquals(0, data.size());
+ public void parseLSanReportFile_nonDigits() throws Exception {
+ parseLSanReport("a b c");
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
- public void parseReportFile_tooFewFields() throws Exception {
- List<List<Object>> data = parseReport("0 1");
- assertEquals(0, data.size());
+ public void parseLSanReportFile_tooFewFields() throws Exception {
+ parseLSanReport("0 1");
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
- public void parseReportFile_tooManyFields() throws Exception {
- List<List<Object>> data = parseReport("0 1 2 3");
- assertEquals(0, data.size());
+ public void parseLSanReportFile_tooManyFields() throws Exception {
+ parseLSanReport("0 1 2 3");
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
- public void parseReportFile_empty() throws Exception {
- List<List<Object>> data = parseReport("");
- assertEquals(0, data.size());
+ public void parseLSanReportFile_empty() throws Exception {
+ parseLSanReport("");
+ verifyZeroInteractions(lsanDBInserter);
}
@Test
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
memAllocationData.add(4338); // PID
memAllocationData.add(4338); // TID
memAllocationData.add(1); // API_ID
- memAllocationData.add("calloc"); // API_TYPE (does not matter)
memAllocationData.add(3024333952L); // ALLOCATED ADDRESS
memAllocationData.add(1000L); // TIME
- memAllocationData.add(3024373978L); // CALLER ADDRESS (does not matter)
memAllocationData.add(3); // CALLER LIBRARY ID
- memAllocationData.add(10); // MESSAGE ID(does not matter)
memAllocationData.add(128L); // ALLOCATED SIZE
TableInput input = HeapDataManager.getInstance()
- .makeTreeInputForLeakData(memAllocationData, 10);
+ .makePersistentAllocsTableInput(memAllocationData, 10, false);
+ assertNotNull(input);
((DATableDataFormat)input.getData()).setType(AnalyzerConstants.TYPE_TABLE_MEM_ALLOCATEDTRACE);
GridItem gridItem = mock(GridItem.class);
GridItem[] items = new GridItem[1];
items[0] = gridItem;
- selData = spy(new DASelectionData(MemoryPage.allocationtraceViewID,
+ selData = spy(new DASelectionData(MemoryPage.persistentAllocsViewID,
1000L, 1000L, items, table));
PowerMockito.when(selData, "getData").thenReturn(items);
assertFalse((Boolean) check.invoke(memTable, badSelData));
badSelData = new DASelectionData(
- MemoryPage.allocationtraceViewID, 1000L, 1000L, null, table);
+ MemoryPage.persistentAllocsViewID, 1000L, 1000L, null, table);
assertFalse((Boolean) check.invoke(memTable, badSelData));
- badSelData = new DASelectionData(MemoryPage.allocationtraceViewID,
+ badSelData = new DASelectionData(MemoryPage.persistentAllocsViewID,
1000L, 1000L, new GridItem[0], table);
assertFalse((Boolean) check.invoke(memTable, badSelData));
((DATableDataFormat) ((GridItem[]) selData.getData())[0].getData())
.setType(AnalyzerConstants.TYPE_TABLE_APP_STARTUP);
- badSelData = new DASelectionData(MemoryPage.allocationtraceViewID,
+ badSelData = new DASelectionData(MemoryPage.persistentAllocsViewID,
1000L, 1000L, selData.getData(), table);
assertFalse((Boolean) check.invoke(memTable, badSelData));
((DATableDataFormat) ((GridItem[]) selData.getData())[0].getData())
"initOptionsSelectedPreferenceList");
assertEquals(1, initOptionsSelectedPreferenceList.size());
assertEquals(2001, initOptionsSelectedPreferenceList.get(0).getIndex());
- assertEquals(-1, initOptionsSelectedPreferenceList.get(0).getValue());
+ assertEquals(1, initOptionsSelectedPreferenceList.get(0).getValue());
}
@Test
List<FlatPreferences> flatPreferenceList = setting.getSelectedPreferencesList();
assertEquals(1, flatPreferenceList.size());
assertEquals(FlatPreferences.SOURCE_VIEW, flatPreferenceList.get(0));
- assertEquals(-1, flatPreferenceList.get(0).getValue());
+ assertEquals(1, flatPreferenceList.get(0).getValue());
flatPreferenceList = Whitebox.getInternalState(setting, "initOptionsSelectedPreferenceList");
assertEquals(1, flatPreferenceList.size());
assertEquals(FlatPreferences.SOURCE_VIEW, flatPreferenceList.get(0));
- assertEquals(-1, flatPreferenceList.get(0).getValue());
+ assertEquals(1, flatPreferenceList.get(0).getValue());
}
@Test
List<FlatPreferences> flatPreferencesList = setting.getSelectedPreferencesList();
assertEquals(1, flatPreferencesList.size());
assertEquals(2001, flatPreferencesList.get(0).getIndex());
- assertEquals(-1, flatPreferencesList.get(0).getValue());
+ assertEquals(1, flatPreferencesList.get(0).getValue());
assertFalse(setting.changedFeatures());
}
.getSelectedPreferencesList();
assertEquals(1, flatPreferencesList.size());
assertEquals(2001, flatPreferencesList.get(0).getIndex());
- assertEquals(-1, flatPreferencesList.get(0).getValue());
+ assertEquals(1, flatPreferencesList.get(0).getValue());
assertFalse(setting.changedFeatures());
}
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
+import org.tizen.dynamicanalyzer.constant.CommonConstants;
import org.tizen.dynamicanalyzer.widgets.button.DACustomButton;
import org.tizen.dynamicanalyzer.widgets.button.DACustomButtonAttribute;
import org.tizen.dynamicanalyzer.widgets.button.DACustomButtonRenderer;
text = new String(charArr);
}
- if (!text.contains("\n")) {
+ if (!text.contains(CommonConstants.NEW_LINE)) {
gc.drawString(text, x, y, true);
} else {
int startY = y;
- String[] splitedText = text.split("\n");
+ String[] splitedText = text.split(CommonConstants.NEW_LINE);
int linelength = splitedText.length;
Point[] pText = new Point[linelength];
});\r
}\r
\r
+ /**\r
+ * Adds given {@code view} to a list of children of this view.\r
+ *\r
+ * @param view {@link DABaseComposite} instance\r
+ * @return {@code true} on success\r
+ */\r
public boolean addView(DABaseComposite view) {\r
return addView(view.getID(), view);\r
}\r
\r
+ /**\r
+ * Adds given {@code view} with specified {@code viewId} to a list of\r
+ * children of this view.\r
+ *\r
+ * @param viewId identification string for given view\r
+ * @param view {@link DABaseComposite} instance\r
+ * @return {@code true} on success\r
+ */\r
public boolean addView(String viewId, DABaseComposite view) {\r
- if (null == viewId || viewId.isEmpty()) {\r
- viewId = view.getClass().getName();\r
- }\r
+ viewId = getViewId(viewId, view);\r
view.setID(viewId);\r
\r
- if (null != childMap.get(viewId)) {\r
+ if (null != childMap.get(viewId))\r
return false;\r
- } else {\r
- childMap.put(viewId, view);\r
- return true;\r
- }\r
+\r
+ childMap.put(viewId, view);\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * Removes given {@code view} from a list of children of this view.\r
+ *\r
+ * @param view {@link DABaseComposite} instance\r
+ * @return {@code true} on success\r
+ */\r
+ public boolean removeView(DABaseComposite view) {\r
+ return removeView(view.getID(), view);\r
+ }\r
+\r
+ /**\r
+ * Removes given {@code view} with specified {@code viewId} from a list of\r
+ * children of this view.\r
+ *\r
+ * @param viewId identification string for given view\r
+ * @param view {@link DABaseComposite} instance\r
+ * @return {@code true} on success\r
+ */\r
+ public boolean removeView(String viewId, DABaseComposite view) {\r
+ viewId = getViewId(viewId, view);\r
+ view.setID(viewId);\r
+\r
+ if (null == childMap.get(viewId))\r
+ return false;\r
+\r
+ childMap.remove(viewId);\r
+ return true;\r
+ }\r
+\r
+ private String getViewId(String viewId, DABaseComposite view) {\r
+ if (null == viewId || viewId.isEmpty())\r
+ return view.getClass().getName();\r
+\r
+ return viewId;\r
}\r
\r
@Override\r
public DATabButton addView(String childId, DABaseComposite child,
boolean usingAnimation) {
+ if (child == null)
+ return null;
+
return addView(childId, child, usingAnimation, false);
}
public DATabButton addView(String childId, DABaseComposite child) {
+ if (child == null)
+ return null;
+
return addView(childId, child, false, false);
}
public DATabButton addView(DABaseComposite child, boolean usingAnimation) {
- return addView(null, child, usingAnimation, false);
+ if (child == null)
+ return null;
+
+ return addView(child.getID(), child, usingAnimation, false);
}
public DATabButton addView(DABaseComposite child) {
- return addView(null, child, false, false);
+ if (child == null)
+ return null;
+
+ return addView(child.getID(), child, false, false);
}
public DATabButton addView(String childId, DABaseComposite child,
boolean usingAnimation, boolean closeable) {
+ if (child == null || children.contains(child))
+ return null;
+
String ID = null;
if (null == childId || childId.isEmpty()) {
ID = child.getClass().getName();
<?xml version="1.0" encoding="UTF-8"?>
<?pde version="3.5"?>
-<product name="%DynamicAnalyzer" uid="org.tizen.dynamicanalyzer.workbench.product" id="org.tizen.dynamicanalyzer.workbench.product" application="org.tizen.dynamicanalyzer.workbench.application" version="2.4.3.qualifier" useFeatures="true" includeLaunchers="true">
+<product name="%DynamicAnalyzer" uid="org.tizen.dynamicanalyzer.workbench.product" id="org.tizen.dynamicanalyzer.workbench.product" application="org.tizen.dynamicanalyzer.workbench.application" version="2.4.4.qualifier" useFeatures="true" includeLaunchers="true">
<aboutInfo>
<image path="icons/about_tizen_sdk.png"/>
<parent>
<artifactId>dynamic-analyzer</artifactId>
<groupId>org.tizen.dynamicanalyzer</groupId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.4-SNAPSHOT</version>
<relativePath>..</relativePath>
</parent>
<groupId>org.tizen.dynamicanalyzer</groupId>
<artifactId>org.tizen.dynamicanalyzer.workbench.product</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.4-SNAPSHOT</version>
<packaging>eclipse-repository</packaging>
<properties>
public final static String MEM_CALLSTACK_KEY_FUNCTION_START_ADDRESS = "start address";
// application list management
+ public final static String UNKNOWN = "unknown";//$NON-NLS-1$
public final static String APPCONTROL = "_AppControl";//$NON-NLS-1$
- public final static String RUNNING_PROCESS = "_Running process_";//$NON-NLS-1$
+ public final static String SPECIAL_APP_PREFIX = "da.id.dummy.app";//$NON-NLS-1$
+ public final static String RUNNING_PROCESS = SPECIAL_APP_PREFIX + ".running";//$NON-NLS-1$
public final static String RUNNING_PROCESS_LABEL = "[Running process]";//$NON-NLS-1$
- public final static String WITHOUT_EXECUTABLE = "_Without executable_";//$NON-NLS-1$
+ public final static String WITHOUT_EXECUTABLE = SPECIAL_APP_PREFIX + ".systemwide";//$NON-NLS-1$
public final static String WITHOUT_EXECUTABLE_LABEL = "[Without executable]";//$NON-NLS-1$
- public final static String COMMON_EXECUTABLE = "_Common executable_";//$NON-NLS-1$
+ public final static String COMMON_EXECUTABLE = SPECIAL_APP_PREFIX + ".executable";//$NON-NLS-1$
public final static String COMMON_EXECUTABLE_LABEL = "[Common executable]";//$NON-NLS-1$
// miscellaneous
}
}
+ // Temporal code until SWAP supports non-root sdbd.
+ // TODO: Remove below a lines
+ boolean enableTempRoot = false;
+ if (!device.getIDevice().isRoot()) {
+ if (CommunicatorUtils.becomeSuperUser(device.getIDevice(), true)) {
+ enableTempRoot = true;
+ } else {
+ Logger.warning("Failed to switch root on for the device: "
+ + device.getIDevice().getSerialNumber());
+ }
+ }
+
// start swap manager
CommunicatorUtils.execShellCommand(device.getIDevice(),
AnalyzerShellCommands.DACOMMAND_RUN_MANAGER);
Thread.sleep(100);
+ // Temporal code until SWAP supports non-root sdbd
+ // TODO: Remove below a lines
+ if (enableTempRoot && !CommunicatorUtils.becomeSuperUser(device.getIDevice(), false)) {
+ Logger.warning("Failed to switch root off for the device: "
+ + device.getIDevice().getSerialNumber());
+ }
// connect control socket
result = createControlSocket();
}
/**
+ * Compose string lines for specified application in pkginfo format.
+ *
+ * @param appID application identifier (also will be used for package id)
+ * @param appLabel displayable application label
+ * @return list of string in pkginfo format
+ */
+ public static List<String> composePkginfoLinesFor(String appID, String appLabel, String appType) {
+ List<String> result = new ArrayList<>();
+ result.add(String.format("%s [%s] %s [%s] %s [%s] %s [1]",
+ PackageInfo.PKGTYPE, AnalyzerConstants.UNKNOWN,
+ PackageInfo.PKGID, appID,
+ PackageInfo.VERSION, AnalyzerConstants.UNKNOWN,
+ PackageInfo.PRELOAD));
+
+ result.add(AppInfo.PROPERTY.APPID.name + ":" + appID);
+ result.add(AppInfo.PROPERTY.PACKAGE.name + ":" + appID);
+ result.add(AppInfo.PROPERTY.LABEL.name + ":" + appLabel);
+ result.add(AppInfo.PROPERTY.APPTYPE.name + ":" + appType);
+ result.add("");
+
+ return result;
+ }
+
+ /**
* Get map of packages installed on selected device.
*
* @param dev {@link DeviceInfo} object presenting selected device
pkginfoLines.add("");
// add lines for running process
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "["
- + AnalyzerConstants.RUNNING_PROCESS + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.RUNNING_PROCESS);
- pkginfoLines.add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.RUNNING_PROCESS);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":"
- + AnalyzerConstants.RUNNING_PROCESS_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_RUNNING);
- pkginfoLines.add("");
+ pkginfoLines.addAll(composePkginfoLinesFor(AnalyzerConstants.RUNNING_PROCESS,
+ AnalyzerConstants.RUNNING_PROCESS_LABEL, AppInfo.APPTYPE_RUNNING));
// add lines for common-executable
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "["
- + AnalyzerConstants.COMMON_EXECUTABLE + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.COMMON_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.COMMON_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":"
- + AnalyzerConstants.COMMON_EXECUTABLE_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_EXEC);
- pkginfoLines.add("");
+ pkginfoLines.addAll(composePkginfoLinesFor(AnalyzerConstants.COMMON_EXECUTABLE,
+ AnalyzerConstants.COMMON_EXECUTABLE_LABEL, AppInfo.APPTYPE_EXEC));
// add lines for without-executable
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "["
- + AnalyzerConstants.WITHOUT_EXECUTABLE + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.WITHOUT_EXECUTABLE);
- pkginfoLines
- .add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.WITHOUT_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":"
- + AnalyzerConstants.WITHOUT_EXECUTABLE_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_NONE);
- pkginfoLines.add("");
+ pkginfoLines.addAll(composePkginfoLinesFor(AnalyzerConstants.WITHOUT_EXECUTABLE,
+ AnalyzerConstants.WITHOUT_EXECUTABLE_LABEL, AppInfo.APPTYPE_NONE));
curDev.updatePackageList(
ApplistManager.parseTizenPkginfo(pkginfoLines, new ArrayList<String>(),
private IDevice device = null;
private BaseCommunicator communicator = null;
- private String selectedAppID = null;
private boolean configSuccess = false;
/**
availableMemps = false;
}
- public void setSelectedAppID(String appID) {
- selectedAppID = appID;
- }
-
- public String getSelectedAppID() {
- return selectedAppID;
- }
-
public IDevice getIDevice() {
return device;
}
return appInfoMap;
}
- public PackageInfo getSelectedPackage(String pkgId) {
- return pkgInfoMap.get(pkgId);
- }
-
public String getPlatformName() {
if (profileName == null) {
// platformName = ProfileInfo.getPlatformName(device); // mobile-2.3.0
}
}
- public final boolean pushData(E data) {
+ public boolean pushData(E data) {
return dataQueue.offer(data);
}
- protected final E pollData() {
+ protected E pollData() {
E data = null;
try {
data = dataQueue.take(); // wait if empty
import org.tizen.dynamicanalyzer.nl.MenuBarLabels;
import org.tizen.dynamicanalyzer.project.Project;
import org.tizen.dynamicanalyzer.setting.FlatFeature;
+import org.tizen.dynamicanalyzer.setting.FlatPreferences;
import org.tizen.dynamicanalyzer.setting.SettingDataManager;
import org.tizen.dynamicanalyzer.shortcut.ShortCutManager;
import org.tizen.dynamicanalyzer.swap.communicator.DataChannelThread;
*/
private void startUpdateHeapDataManager() {
if(SettingDataManager.INSTANCE.getSelectedFlatFeatureSet().contains(FlatFeature.MEMORY_ALLOC)) {
- Thread calculateAllocData = new Thread(new Runnable() {
+ Display.getDefault().asyncExec(new Runnable() {
+
+ @Override
public void run() {
- Logger.info("Run : HeapDataManager for calculating alloc data");
- HeapDataManager.getInstance().makeWholeAllocationTraceData();
+ Logger.info("Calculating allocation data in HeapDataManager");
+ if (SettingDataManager.INSTANCE
+ .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER))
+ HeapDataManager.getInstance().makeWholePersistentAllocsData(true);
+
+ if (MenuBar.getInstance().getPersistentAllocationsSelection())
+ HeapDataManager.getInstance().makeWholePersistentAllocsData(false);
+
HeapDataManager.getInstance().makeStatisticsData(0, 0);
- Display.getDefault().syncExec(new Runnable() {
- @Override
- public void run() {
- BaseView baseView = (BaseView) WorkbenchUtil.getViewPart(BaseView.ID);
- baseView.getTopComposite().updateView();
- }
- });
+ BaseView baseView = (BaseView) WorkbenchUtil.getViewPart(BaseView.ID);
+ baseView.getTopComposite().updateView();
}
- }, "CalculateAllocDataThread");
- calculateAllocData.start();
+ });
}
}
public static String MEMORY_RANGE_ANALYSIS_VIEW_NO_RANGES_LABEL;
public static String MEMORY_STATISTICS_VIEW_TITLE;
public static String MEMORY_ALLOCATION_TRACE_VIEW_TITLE;
+ public static String MEMORY_LEAKS_VIEW_TITLE;
public static String MEMORY_MAIN_EXCUTABLE;
public static String MEMORY_DETAILS_VIEW_ITEM;
MEMORY_RANGE_ANALYSIS_VIEW_NO_RANGES_LABEL=There are no ranges. Please create new ranges using markers...\r
MEMORY_STATISTICS_VIEW_TITLE=Statistics\r
MEMORY_ALLOCATION_TRACE_VIEW_TITLE=Persistent Allocations\r
+MEMORY_LEAKS_VIEW_TITLE=Leaks\r
MEMORY_MAIN_EXCUTABLE=Main Executable\r
\r
MEMORY_DETAILS_VIEW_ITEM\r
public static String VIEW_FAILED_API;
public static String VIEW_WARNING;
public static String VIEW_FUNCTION_PROFILING;
- public static String VIEW_PERSISTENT_MEMORY;
+ public static String VIEW_PERSISTENT_ALLOCATIONS;
public static String VIEW_NAVIGATE;
public static String VIEW_ZOOM_IN;
public static String VIEW_ZOOM_OUT;
VIEW_FAILED_API=Failed API
VIEW_WARNING=Warning
VIEW_FUNCTION_PROFILING=Function Profiling
-VIEW_PERSISTENT_MEMORY=Persistent Memory Charts
+VIEW_PERSISTENT_ALLOCATIONS=Persistent Allocations
VIEW_NAVIGATE=Navigate
VIEW_ZOOM_IN=Zoom In
VIEW_ZOOM_OUT=Zoom Out
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
}
/**
+ * Tell whether this app info represents special app entry, e.g. running process.
+ */
+ public boolean isSpecialApp() {
+ return getAppID().startsWith(AnalyzerConstants.SPECIAL_APP_PREFIX);
+ }
+
+ /**
* Get application label with some info about identifier.</br>
* Returns string in next format:</br>
* {@code "<AppLabel> (<LastSubdomain>)"}, where</br>
* <li>{@code <LastSubdomain>} is last subdomain from application id, e.g.</br>
* for "org.tizen.dynamicanalyzer.widgets" last subdomain is "widgets"</li>
* </ul>
+ *
+ * Note: for special applications only label {@code "<AppLabel>"} will be returned.
*/
public String getDistinguishedLabel() {
+ // return only application label for special apps
+ if (isSpecialApp()) {
+ return getLabel();
+ }
+
String[] appIdParts = getAppID().split("\\.");
String detail;
- Logger.debug("App id: %s, parts: %s", getAppID(), Arrays.toString(appIdParts));
if (appIdParts.length == 0)
detail = getPackageID();
else
Logger.debug("Pulled LeakSanitizer report file: " + source);
// Pass pulled file to HeapDataManager
- HeapDataManager.getInstance().parseReportFile(destination);
+ HeapDataManager.getInstance().parseLSanReportFile(destination);
break;
case ERROR:
private boolean isNotSupportedProtocol() {
Protocol usedProtocol = Global.getCurrentProtocol();
return usedProtocol != null
+ && usedProtocol != Protocol.VERSION_UNKNOWN
&& usedProtocol.getVersionNum() < Protocol.VERSION_41.getVersionNum();
}
import org.eclipse.swt.widgets.Composite;
import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
import org.tizen.dynamicanalyzer.nl.AnalyzerLabels;
+import org.tizen.dynamicanalyzer.nl.MemoryPageLabels;
import org.tizen.dynamicanalyzer.resources.ColorResources;
+import org.tizen.dynamicanalyzer.setting.FlatPreferences;
+import org.tizen.dynamicanalyzer.setting.SettingDataManager;
import org.tizen.dynamicanalyzer.shortcut.ShortCutManager;
import org.tizen.dynamicanalyzer.ui.memory.chart.MemoryChartBoard;
import org.tizen.dynamicanalyzer.ui.memory.data.HeapDataManager;
import org.tizen.dynamicanalyzer.ui.memory.data.MemoryDataManager;
import org.tizen.dynamicanalyzer.ui.memory.table.MemoryPersistentAllocationsTable;
import org.tizen.dynamicanalyzer.ui.memory.table.MemoryStatisticsTable;
+import org.tizen.dynamicanalyzer.ui.page.MenuBar;
import org.tizen.dynamicanalyzer.ui.widgets.table.DABaseDataPageComposite;
+import org.tizen.dynamicanalyzer.widgets.da.view.DABaseComposite;
import org.tizen.dynamicanalyzer.widgets.da.view.DATabComposite;
public class MemoryPage extends DABaseDataPageComposite {
public static final String chartViewID = MemoryChartView.class.getName();
public static final String detailsViewID = MemoryDetailsTableView.class.getName();
public static final String mapViewID = MemoryMapView.class.getName();
- public static final String allocationtraceViewID = MemoryPersistentAllocationsTableView.class.getName();
+ public static final String persistentAllocsViewID = MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_TITLE + "View";
+ public static final String leaksViewID = MemoryPageLabels.MEMORY_LEAKS_VIEW_TITLE + "View";
private DATabComposite memoryTabView = null;
MemoryDetailsTableView memoryDetailsTableView;
MemoryRangeAnalysisView memoryRangeAnalysisView;
MemoryStatisticsTableView memoryStatisticsTableView;
- MemoryPersistentAllocationsTableView memoryAllocationTraceTableView;
+ MemoryPersistentAllocationsTableView memoryPersistentAllocationsTableView;
+ MemoryPersistentAllocationsTableView memoryLeaksTableView;
MemoryMapView memoryMapView;
MemoryCallStackView memoryCallStackView;
memoryTabView.addView(memoryStatisticsTableView, false);
addView(memoryStatisticsTableView);
- memoryAllocationTraceTableView = new MemoryPersistentAllocationsTableView(memoryTabView.getContentComposite(), SWT.NONE);
- ((MemoryPersistentAllocationsTable) memoryAllocationTraceTableView.getControl())
- .getTable().addSelectionListener(new PersistentAllocationsSelectionListener(this));
- memoryTabView.addView(memoryAllocationTraceTableView, false);
- addView(memoryAllocationTraceTableView);
+ PersistentAllocationsSelectionListener persistentAllocsListener = new PersistentAllocationsSelectionListener(
+ this);
+
+ memoryPersistentAllocationsTableView = new MemoryPersistentAllocationsTableView(
+ memoryTabView.getContentComposite(), SWT.NONE, false);
+ ((MemoryPersistentAllocationsTable) memoryPersistentAllocationsTableView.getControl())
+ .getTable().addSelectionListener(persistentAllocsListener);
+ showView(memoryPersistentAllocationsTableView,
+ MenuBar.getInstance().getPersistentAllocationsSelection());
+
+ memoryLeaksTableView = new MemoryPersistentAllocationsTableView(
+ memoryTabView.getContentComposite(), SWT.NONE, true);
+ ((MemoryPersistentAllocationsTable) memoryLeaksTableView.getControl()).getTable()
+ .addSelectionListener(persistentAllocsListener);
+ showView(memoryLeaksTableView, SettingDataManager.INSTANCE
+ .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER));
}
addView(memoryTabView);
memoryRangeAnalysisView.setStatisticsSortListener(statisticsSortListener);
}
+ /**
+ * Shows or hides given {@code view} depending on the value of the
+ * {@code show} argument.
+ *
+ * @param view {@link DABaseComposite} instance
+ * @param show whether {@code view} should be shown
+ */
+ private void showView(DABaseComposite view, boolean show) {
+ if (show) {
+ memoryTabView.addView(view);
+ addView(view);
+ } else {
+ memoryTabView.removeView(view.getID(), false);
+ removeView(view);
+ }
+ resizeTableButton();
+ }
+
+ /**
+ * Shows or hides 'Persistent Allocations' table depending on the value of
+ * the {@code show} argument.
+ *
+ * @param show whether the table should be shown
+ */
+ public void showPersistentAllocationsView(boolean show) {
+ showView(memoryPersistentAllocationsTableView, show);
+
+ // forces table to be updated when the view will be shown again
+ if (!show)
+ memoryPersistentAllocationsTableView.hide();
+ }
+
+ /**
+ * Shows or hides 'Leaks' table depending on the value of the {@code show}
+ * argument.
+ *
+ * @param show whether the table should be shown
+ */
+ public void showLeaksView(boolean show) {
+ showView(memoryLeaksTableView, show);
+
+ // forces table to be updated when the view will be shown again
+ if (!show)
+ memoryLeaksTableView.hide();
+ }
+
@Override
public void clear() {
super.clear();
import org.tizen.dynamicanalyzer.widgets.da.view.DAViewData;
public class MemoryPersistentAllocationsTableView extends DAHidableViewComposite {
-
- public static final String ID = MemoryPersistentAllocationsTableView.class.getName();
-
+
private MemoryPersistentAllocationsTable tableComp = null;
- public MemoryPersistentAllocationsTableView(Composite parent, int style) {
+ private boolean onlyLeaks = false;
+
+ public MemoryPersistentAllocationsTableView(Composite parent, int style, boolean onlyLeaks) {
super(parent, style, false, MemoryPageLabels.STREAMING_NOT_SUPPORTED);
- setTitle(MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_TITLE);
+ this.onlyLeaks = onlyLeaks;
+
+ setTitle(onlyLeaks
+ ? MemoryPageLabels.MEMORY_LEAKS_VIEW_TITLE
+ : MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_TITLE);
+
+ ID = onlyLeaks ? MemoryPage.leaksViewID : MemoryPage.persistentAllocsViewID;
tableComp = new MemoryPersistentAllocationsTable(getContentArea(), SWT.NONE,
- SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
+ SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL, onlyLeaks);
setDataComposite(tableComp);
- setLeakColumnVisible(SettingDataManager.INSTANCE
- .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER));
}
@Override
public void updateView() {
- boolean pref = SettingDataManager.INSTANCE
- .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER);
- boolean cur = tableComp
- .getColumnVisibility()[MemoryPersistentAllocationsTableIndex.LEAK.getIndex()];
- if (pref != cur) {
- setLeakColumnVisible(pref);
- tableComp.cleanColumnsWeights();
- tableComp.resizeColumns(this.getSize().x);
+ if (!onlyLeaks) {
+ boolean pref = SettingDataManager.INSTANCE
+ .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER);
+ boolean cur = tableComp.getColumnVisibility()[MemoryPersistentAllocationsTableIndex.LEAK
+ .getIndex()];
+ if (pref != cur) {
+ setLeakColumnVisible(pref);
+ tableComp.cleanColumnsWeights();
+ tableComp.resizeColumns(this.getSize().x);
+ }
}
if (DAState.isRunning()) {
show();
}
- setLeakColumnVisible(SettingDataManager.INSTANCE
- .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER));
+ if (!onlyLeaks)
+ setLeakColumnVisible(SettingDataManager.INSTANCE
+ .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER));
tableComp.updateTable();
}
\r
public MemoryChartBoard(Composite parent, String title, int boardStyle) {\r
super(parent, title, boardStyle);\r
- showPersistentSeries = MenuBar.getInstance().getPersistentMemoryChartsSelection();\r
+ showPersistentSeries = MenuBar.getInstance().getPersistentAllocationsSelection();\r
}\r
\r
public void initalizeChart() {\r
// no need to select data from DB every time if it is not\r
// changing\r
if (persistentData == null)\r
- persistentData = HeapDataManager.getInstance().remainedAllocatedListForRange(start, end);\r
+ persistentData = HeapDataManager.getInstance()\r
+ .remainedAllocatedListForRange(start, end, false);\r
\r
heapChart.showPersistentSeries();\r
heapChart.updatePersistentSeries(persistentData);\r
import org.tizen.dynamicanalyzer.model.TableInput;
import org.tizen.dynamicanalyzer.model.TreeInput;
import org.tizen.dynamicanalyzer.nl.MemoryPageLabels;
+import org.tizen.dynamicanalyzer.project.Project;
import org.tizen.dynamicanalyzer.protocol.Protocol;
import org.tizen.dynamicanalyzer.protocol.ProtocolConstants;
import org.tizen.dynamicanalyzer.setting.FlatPreferences;
import org.tizen.dynamicanalyzer.swap.logparser.PageDataManager;
import org.tizen.dynamicanalyzer.swap.model.data.LogData;
import org.tizen.dynamicanalyzer.swap.model.data.MemoryData;
+import org.tizen.dynamicanalyzer.ui.memory.table.MemoryPersistentAllocationsTable;
import org.tizen.dynamicanalyzer.ui.toolbar.Toolbar;
import org.tizen.dynamicanalyzer.ui.widgets.table.DATableDataFormat;
import org.tizen.dynamicanalyzer.util.Logger;
import org.tizen.dynamicanalyzer.utils.Formatter;
public class HeapDataManager extends PageDataManager {
-
+
+ /**
+ * Class representing basic SQL query executed by {@link HeapDataManager}.
+ */
+ private static class Query {
+ /**
+ * Start time of selected time range.
+ */
+ public long startTime;
+ /**
+ * End time of selected time range.
+ */
+ public long endTime;
+ /**
+ * String representation of selected PIDs.
+ */
+ public String pidString;
+
+ /**
+ * Default constructor.
+ */
+ public Query() {
+ clear();
+ }
+
+ /**
+ * Constructs new instance with given time range.
+ *
+ * @param startTime start time of selected time range
+ * @param endTime end time of selected time range
+ */
+ public Query(long startTime, long endTime) {
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.pidString = getTargetPIDString();
+ }
+
+ /**
+ * Resets values of all fields to defaults.
+ */
+ public void clear() {
+ startTime = -1L;
+ endTime = -1L;
+ pidString = "";
+ }
+
+ /**
+ * Auto-generated method.
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (int) (endTime ^ (endTime >>> 32));
+ result = prime * result + ((pidString == null) ? 0 : pidString.hashCode());
+ result = prime * result + (int) (startTime ^ (startTime >>> 32));
+ return result;
+ }
+
+ /**
+ * Auto-generated method.
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (!(obj instanceof Query))
+ return false;
+ Query other = (Query) obj;
+ if (endTime != other.endTime)
+ return false;
+ if (pidString == null) {
+ if (other.pidString != null)
+ return false;
+ } else if (!pidString.equals(other.pidString))
+ return false;
+ if (startTime != other.startTime)
+ return false;
+ return true;
+ }
+
+ /**
+ * Constructs string representation of currently selected PIDs.
+ *
+ * @return string representation of currently selected PIDs
+ */
+ private static String getTargetPIDString() {
+ // TODO: move this method to some utility class and generalize all
+ // SQL queries management.
+
+ StringBuilder pidliststring = new StringBuilder();
+ pidliststring.append(CommonConstants.OPEN_BRACKET);
+
+ int targetPID = Toolbar.INSTANCE.getSelectedPid();
+
+ if (targetPID > 0)
+ pidliststring.append(targetPID);
+ else
+ for (int pid : Global.getProject().getProcessIDs()) {
+ if (pidliststring.length() != 1)
+ pidliststring.append(CommonConstants.COMMA);
+
+ pidliststring.append(pid);
+ }
+
+ pidliststring.append(CommonConstants.CLOSE_BRACKET);
+
+ return pidliststring.toString();
+ }
+ }
+
private static HeapDataManager instance = new HeapDataManager();
private final int TOTAL_PID = -1;
private int REALLOC_ID;
- private MemAllocDBTable allocateDBTable = null;
- private MemFreeDBTable freeDBTable = null;
- private MemLSanTable lsanDBTable = null;
+ private MemAllocDBTable allocateDBTable = new MemAllocDBTable();
+ private MemFreeDBTable freeDBTable = new MemFreeDBTable();
+ private MemLSanTable lsanDBTable = new MemLSanTable();
- private DBInserter allocateDBInserter = null;
- private DBInserter freeDBInserter = null;
- private DBInserter lsanDBInserter = null;
+ private DBInserter allocateDBInserter = makeInserter(allocateDBTable);
+ private DBInserter freeDBInserter = makeInserter(freeDBTable);
+ private DBInserter lsanDBInserter = makeInserter(lsanDBTable);
private ArrayList<List<Object>> memoryAllocDataList = new ArrayList<List<Object>> ();
private ArrayList<List<Object>> memoryfreeDataList = new ArrayList<List<Object>> ();
- private List<TableInput> allocationTraceTreeInput = new ArrayList<TableInput>();
- private List<TreeInput> statisticsTreeInput = new ArrayList<TreeInput>();
+ private volatile List<TableInput> persistentAllocsTableInput = new ArrayList<TableInput>();
+ private volatile List<TableInput> leaksTableInput = new ArrayList<TableInput>();
+ private volatile List<TreeInput> statisticsTreeInput = new ArrayList<TreeInput>();
private List<List<Object>> preAllocDataList = new ArrayList<List<Object>>();
private List<List<Object>> preFreeDataList = new ArrayList<List<Object>>();
- private List<List<Object>> lsanDataList = new ArrayList<List<Object>>();
+ private List<List<Object>> preLeaksAllocDataList = new ArrayList<List<Object>>();
+ private List<List<Object>> preLeaksFreeDataList = new ArrayList<List<Object>>();
private HashSet<Long> addressMap = new HashSet<Long> ();
- private List<Object> preQueryTime = new ArrayList<Object>();
-
- private Object lockAllocationCal = new Object();
- private Object lockStatisticsCal = new Object();
-
- private HeapDataManager() {
- allocateDBTable = new MemAllocDBTable();
- freeDBTable = new MemFreeDBTable();
- lsanDBTable = new MemLSanTable();
-
- allocateDBInserter = makeInserter(allocateDBTable);
- freeDBInserter = makeInserter(freeDBTable);
- lsanDBInserter = makeInserter(lsanDBTable);
-
- // 0 : start time
- // 1 : end time
- // 2 : pid list
- preQueryTime.add((long) -1);
- preQueryTime.add((long) -1);
- preQueryTime.add((String) "");
- }
+ private Query lastFullAllocsQuery = new Query();
+ private Query lastLeaksQuery = new Query();
public static HeapDataManager getInstance() {
return instance;
addressMap.clear();
- allocationTraceTreeInput.clear();
+ persistentAllocsTableInput.clear();
+ leaksTableInput.clear();
statisticsTreeInput.clear();
preAllocDataList.clear();
preFreeDataList.clear();
- lsanDataList.clear();
+ preLeaksAllocDataList.clear();
+ preLeaksFreeDataList.clear();
- preQueryTime.clear();
-
- // 0 : start time
- // 1 : end time
- // 2 : pid list
- preQueryTime.add((long) -1);
- preQueryTime.add((long) -1);
- preQueryTime.add((String) "");
+ lastFullAllocsQuery.clear();
+ lastLeaksQuery.clear();
}
@Override
return (Long) queryResult.get(0).get(0);
}
- private List<List<Object>> getAllocationDataFromDB(long start, long end, String targetPIDs) {
- List<List<Object>> allocatedResult = new ArrayList<List<Object>> ();
-
- String where = getTimeWhereQuery(start, end, targetPIDs, MemAllocDBTable.COLUMN.ALLOCATED_TIME.name);
+ /**
+ * Selects all data from basic columns of {@link MemAllocDBTable} using
+ * specified {@code query} and optionally filters leaks depending on
+ * {@code onlyLeaks} argument.
+ *
+ * @param query {@link Query} instance
+ * @param onlyLeaks whether only leaks data should be selected
+ * @return selected data from database
+ */
+ private List<List<Object>> getAllocationDataFromDB(Query query, boolean onlyLeaks) {
+ String where = getTimeWhereQuery(query, MemAllocDBTable.COLUMN.ALLOCATED_TIME.name,
+ onlyLeaks);
where += " ORDER BY " + MemAllocDBTable.COLUMN.SEQUENCE_NUMBER.name;
List<List<Object>> queryResult = allocateDBTable.selectBasicColumns(where);
- if (queryResult == null) {
- return allocatedResult;
- }
- allocatedResult = queryResult;
- return allocatedResult;
+ return queryResult != null ? queryResult : new ArrayList<List<Object>>();
}
- private List<List<Object>> getFreeDataFromDB(long start, long end, String targetPIDs) {
- List<List<Object>> freeResult = new ArrayList<List<Object>> ();
-
- String where = getTimeWhereQuery(start, end, targetPIDs, MemFreeDBTable.COLUMN.FREE_TIME.name);
+ /**
+ * Selects all data from basic columns of {@link MemFreeDBTable} using
+ * specified {@code query} and optionally filters leaks depending on
+ * {@code onlyLeaks} argument.
+ *
+ * @param query {@link Query} instance
+ * @param onlyLeaks whether only leaks data should be selected
+ * @return selected data from database
+ */
+ private List<List<Object>> getFreeDataFromDB(Query query, boolean onlyLeaks) {
+ String where = getTimeWhereQuery(query, MemFreeDBTable.COLUMN.FREE_TIME.name, onlyLeaks);
where += " ORDER BY " + MemFreeDBTable.COLUMN.SEQUENCE_NUMBER.name;
List<List<Object>> queryResult = freeDBTable.selectBasicColumns(where);
- if (queryResult == null) {
- return freeResult;
- }
- freeResult = queryResult;
- return freeResult;
+ return queryResult != null ? queryResult : new ArrayList<List<Object>>();
}
-
- public void makeWholeAllocationTraceData() {
+
+ /**
+ * Calculates and caches data for 'Persistent Allocations' or 'Leaks' table
+ * depending on {@code onlyLeaks} argument.
+ *
+ * @param onlyLeaks whether only leaks data should be cached
+ */
+ public void makeWholePersistentAllocsData(boolean onlyLeaks) {
if(DAState.isRunning() == true) {
return;
}
List<List<Object>> allocDataList = null;
- String pidliststring = getTargetPIDString();
- allocDataList = remainedAllocatedListForRange(0, 0, pidliststring);
+ allocDataList = remainedAllocatedListForRange(0L, 0L, onlyLeaks);
if (allocDataList == null || allocDataList.size() == 0)
return;
for (int j = 0; j < size; j++) {
List<Object> iAllocData = allocDataList.get(j);
-
- TableInput alloInput = makeTreeInputForLeakData(iAllocData, index++);
-
- if (alloInput != null){
- output.add(alloInput);
- }
- }
-
- synchronized(lockAllocationCal) {
- allocationTraceTreeInput = output;
+ TableInput input = makePersistentAllocsTableInput(iAllocData, index++, onlyLeaks);
+ if (input != null)
+ output.add(input);
}
+
+ if (onlyLeaks)
+ leaksTableInput = output;
+ else
+ persistentAllocsTableInput = output;
}
/**
* end time of selected range
*/
public void makeStatisticsData(long startTime, long endTime) {
- String pidliststring = getTargetPIDString();
-
- Map<Integer, Map<Integer, List<Object>>> staticdatas = remainedAllocStaticData(startTime, endTime,
- pidliststring);
+ Query query = new Query(startTime, endTime);
+ Map<Integer, Map<Integer, List<Object>>> staticdatas = remainedAllocStaticData(query);
int index = 0;
List<TreeInput> output = new ArrayList<TreeInput>();
output.add(parent);
}
- synchronized(lockStatisticsCal) {
- statisticsTreeInput = output;
- }
+ statisticsTreeInput = output;
}
-
- public List<TableInput> getWholeAllocationTraceTreeInput() {
- List<TableInput> output = null;
-
- synchronized(lockAllocationCal) {
- if(this.allocationTraceTreeInput == null)
- this.allocationTraceTreeInput = new ArrayList<TableInput>();
-
- output = this.allocationTraceTreeInput;
- }
- return output;
+
+ /**
+ * Gets data for 'Persistent Allocations' table.
+ *
+ * @return list of {@link TableInput}
+ */
+ public List<TableInput> getPersistentAllocsTableInput() {
+ return persistentAllocsTableInput;
}
-
+
+ /**
+ * Gets data for 'Leaks' table.
+ *
+ * @return list of {@link TableInput}
+ */
+ public List<TableInput> getLeaksTableInput() {
+ return leaksTableInput;
+ }
+
public List<TreeInput> getStatisticsTreeInput() {
- List<TreeInput> output = null;
-
- synchronized(lockStatisticsCal) {
- if(this.statisticsTreeInput == null)
- this.statisticsTreeInput = new ArrayList<TreeInput>();
-
- output = this.statisticsTreeInput;
- }
- return output;
+ return statisticsTreeInput;
}
- public Map<Integer, Map<Integer, List<Object>>> remainedAllocStaticData(long startTime, long endTime,
- String targetPIDs) {
- getAllocationFreeDatas(startTime, endTime, targetPIDs);
-
- Map<Integer, Map<Integer, List<Object>>> result = makeRemainedAllocatedStatic(preAllocDataList,
- preFreeDataList);
-
- return result;
+ private Map<Integer, Map<Integer, List<Object>>> remainedAllocStaticData(Query query) {
+ updateFullAllocCache(query);
+ return makeRemainedAllocatedStatic(preAllocDataList, preFreeDataList);
}
- public List<List<Object>> remainedAllocatedListForRange(long startTime, long endTime) {
- return remainedAllocatedListForRange(startTime, endTime, getTargetPIDString());
+ public List<List<Object>> remainedAllocatedListForRange(long startTime, long endTime,
+ boolean onlyLeaks) {
+ Query query = new Query(startTime, endTime);
+ return remainedAllocatedListForRange(query, onlyLeaks);
}
- public List<List<Object>> remainedAllocatedListForRange(long startTime, long endTime, String targetPIDs) {
-
- List<List<Object>> rangeDataList = new ArrayList<List<Object>> ();
-
- getAllocationFreeDatas(startTime, endTime, targetPIDs);
-
- if (preAllocDataList != null) {
- if (preFreeDataList == null) {
- rangeDataList.addAll(preAllocDataList);
- } else {
- List<List<Object>> result = makeRemainedAllocatedList(preAllocDataList, preFreeDataList);
- if (result != null && !result.isEmpty())
- rangeDataList.addAll(result);
- }
+ private List<List<Object>> remainedAllocatedListForRange(Query query, boolean onlyLeaks) {
+ if (onlyLeaks) {
+ updateLeaksCache(query);
+ return makeRemainedAllocatedList(preLeaksAllocDataList, preLeaksFreeDataList);
}
-
- return rangeDataList;
+
+ updateFullAllocCache(query);
+ return makeRemainedAllocatedList(preAllocDataList, preFreeDataList);
}
/**
return output;
}
-
- public TableInput makeTreeInputForLeakData(List<Object> allocData, int index) {
+
+ /**
+ * Constructs {@link TableInput} for
+ * {@link MemoryPersistentAllocationsTable} using specified allocation data,
+ * index and adds a 'Leak' column data if {@code onlyLeaks} argument is set
+ * to {@code false}.
+ *
+ * @param allocData data selected from {@link MemAllocDBTable}
+ * @param index index of new {@link TableInput}
+ * @param onlyLeaks whether new {@link TableInput} will be used in 'Leaks'
+ * table, if set to {@code false}, 'Leak' column data will be
+ * added
+ * @return constructed instance of {@link TableInput} on success and
+ * {@code null} otherwise
+ */
+ public TableInput makePersistentAllocsTableInput(List<Object> allocData, int index,
+ boolean onlyLeaks) {
DATableDataFormat tableData = new DATableDataFormat(index);
List<String> text = new ArrayList<String>();
if (libName == null || libName.isEmpty()) {
libName = AnalyzerConstants.UNKNOWN_LIB;
}
+
+ // Check if allocation was made from main binary
+ Project project = Global.getProject();
+ boolean isMainBinary = project != null && project.getApplicationInfo() != null
+ && project.getApplicationInfo().getExecBinaryPath().equals(libName);
+
+ // Filter leaks not from application binary
+ if (onlyLeaks && !isMainBinary)
+ return null;
+
text.add(libName);
data.add(libName);
// 7 : api type
text.add(apiName);
data.add(apiName);
- // 8 : leak
- boolean leak = false;
+ if (!onlyLeaks) {
+ // 8 : leak
+ boolean leak = false;
- if (SettingDataManager.INSTANCE.isPreferenceSelected(FlatPreferences.LEAK_SANITIZER)) {
- if (lsanDataList.isEmpty())
- lsanDataList = lsanDBTable.selectAllColumnData("");
+ if (isMainBinary && SettingDataManager.INSTANCE
+ .isPreferenceSelected(FlatPreferences.LEAK_SANITIZER)) {
+ updateLeaksCache(new Query(0L, 0L));
+ leak = preLeaksAllocDataList.contains(allocData);
+ }
- for (List<Object> row : lsanDataList)
- if (((Long) row.get(0)).equals(address)) {
- leak = true;
- break;
- }
+ text.add(leak ? CommonConstants.YES : CommonConstants.EMPTY);
+ data.add(leak ? CommonConstants.YES : CommonConstants.EMPTY);
}
- text.add(leak ? CommonConstants.YES : CommonConstants.EMPTY);
- data.add(leak ? CommonConstants.YES : CommonConstants.EMPTY);
-
tableData.setType(AnalyzerConstants.TYPE_TABLE_MEM_ALLOCATEDTRACE);
TreeInput output = new TreeInput();
}
/**
- * Parses given report file.
+ * Parses given LeakSanitizer report file.
*
* @param filepath path to pulled report file on host
*/
- public void parseReportFile(String filepath) {
+ public void parseLSanReportFile(String filepath) {
Scanner scanner = null;
- lsanDataList.clear();
+ List<List<Object>> lsanDataList = new ArrayList<List<Object>>();
String parsingErrorMsg = "Failed to parse file: " + filepath;
lsanDataList.add(row);
}
- lsanDBInserter.pushData(lsanDataList);
+ if (!lsanDataList.isEmpty())
+ lsanDBInserter.pushData(lsanDataList);
} catch (FileNotFoundException e) {
Logger.warning("File was not found: " + filepath);
scanner.close();
}
}
-
- private String getTargetPIDString(){
- List<Integer> pidlist = new ArrayList<Integer>();
-
- int[] pids = Global.getProject().getProcessIDs();
- int targetPID = Toolbar.INSTANCE.getSelectedPid();
-
- if(targetPID > 0) {
- pidlist.add(targetPID);
- }
- else {
- for (int i = 0; i < pids.length; i++) {
- pidlist.add(pids[i]);
- }
- }
-
- StringBuilder pidliststring = new StringBuilder();
- pidliststring.append("(");
-
- for(int i = 0 ; i < pidlist.size() ; i++) {
- pidliststring.append(Integer.toString(pidlist.get(i)));
-
- if(i != pidlist.size() - 1) {
- pidliststring.append(", ");
- }
- }
-
- pidliststring.append(")");
-
- return pidliststring.toString();
- }
private Logs getLogsFromLogPackage(LogPackage logPack, int logCenterConstants) {
Logs logs = logPack.getLogs(logCenterConstants);
memoryfreeDataList.add(dbFreeData);
}
-
- private String getTimeWhereQuery(long start, long end, String targetIds, String timecolumn) {
- String where = "WHERE";
- if (start != 0 || end != 0) {
- where += String.format(" %s BETWEEN %s AND %s AND", timecolumn, Long.toString(start), Long.toString(end));
+
+ /**
+ * Constructs string representation of query conditions: time range, pid
+ * list and optional INNER JOIN with {@link MemLSanTable} if
+ * {@code onlyLeaks} is set as {@code true}.
+ *
+ * @param query {@link Query} instance
+ * @param timecolumn name of the column used for time data
+ * @param onlyLeaks whether result should filtered by data from
+ * {@link MemLSanTable}
+ * @return string representation of query conditions
+ */
+ private String getTimeWhereQuery(Query query, String timecolumn, boolean onlyLeaks) {
+ StringBuilder where = new StringBuilder();
+ if (onlyLeaks) {
+ String table1 = "table1";
+ String table2 = "table2";
+ String joinCol = MemLSanTable.COLUMN.ALLOCATED_ADDRESS.name;
+ String join = String.format("%s INNER JOIN %s %s ON %s.%s = %s.%s ", table1,
+ MemLSanTable.TABLENAME, table2, table1, joinCol, table2, joinCol);
+ where.append(join);
}
-
- where += String.format(" PID IN %s", targetIds);
-
- return where;
+
+ where.append("WHERE ");
+ if (query.startTime != 0 || query.endTime != 0) {
+ String timeRange = String.format("%s BETWEEN %s AND %s AND ", timecolumn,
+ Long.toString(query.startTime), Long.toString(query.endTime));
+ where.append(timeRange);
+ }
+
+ where.append(String.format("PID IN %s", query.pidString));
+
+ return where.toString();
}
-
- private void getAllocationFreeDatas(long start, long end, String targetIds) {
-
- if((Long)preQueryTime.get(0) == start &&
- (Long)preQueryTime.get(1) == end &&
- ((String)preQueryTime.get(2)).equals(targetIds)) {
+
+ /**
+ * Selects and caches all data from {@link MemAllocDBTable} and
+ * {@link MemFreeDBTable}, using specified {@code query} if it has changed
+ * since the last time.
+ *
+ * @param query {@link Query} instance
+ */
+ private void updateFullAllocCache(Query query) {
+ if (lastFullAllocsQuery.equals(query))
return;
- }
-
+
+ lastFullAllocsQuery = query;
+
// TODO: Add check for data size to be loaded from data base.
// If data size exceeds predefined limit - invoke DALimit.stopTraceAndOpenWarningDialog()
- preAllocDataList = getAllocationDataFromDB(start, end, targetIds);
- preFreeDataList = getFreeDataFromDB(start, end, targetIds);
-
- preQueryTime.set(0, start);
- preQueryTime.set(1, end);
- preQueryTime.set(2, targetIds);
+ preAllocDataList = getAllocationDataFromDB(lastFullAllocsQuery, false);
+ preFreeDataList = getFreeDataFromDB(lastFullAllocsQuery, false);
}
-
+
+ /**
+ * Selects and caches all data from {@link MemAllocDBTable} and
+ * {@link MemFreeDBTable} inner joined with {@link MemLSanTable}, using
+ * specified {@code query} if it has changed since the last time.
+ *
+ * @param query {@link Query} instance
+ */
+ private void updateLeaksCache(Query query) {
+ if (lastLeaksQuery.equals(query))
+ return;
+
+ lastLeaksQuery = query;
+
+ // TODO: Add check for data size to be loaded from data base.
+ // If data size exceeds predefined limit - invoke DALimit.stopTraceAndOpenWarningDialog()
+ preLeaksAllocDataList = getAllocationDataFromDB(lastLeaksQuery, true);
+ preLeaksFreeDataList = getFreeDataFromDB(lastLeaksQuery, true);
+ }
+
private static class AscCompare implements Comparator<LogData> {
@Override
import org.tizen.dynamicanalyzer.model.TableInput;
import org.tizen.dynamicanalyzer.project.callstack.RuntimeCallstackManager;
import org.tizen.dynamicanalyzer.ui.info.callstack.CallStackUnit;
-import org.tizen.dynamicanalyzer.ui.memory.MemoryPersistentAllocationsTableView;
+import org.tizen.dynamicanalyzer.ui.memory.MemoryPage;
import org.tizen.dynamicanalyzer.ui.memory.data.HeapDataManager;
import org.tizen.dynamicanalyzer.ui.memory.data.MemAllocDBTable;
import org.tizen.dynamicanalyzer.ui.timeline.common.TimelineTableView;
return false;
}
String viewId = selData.getViewID();
- if (!viewId.equals(MemoryPersistentAllocationsTableView.class
- .getName()))
+ if (!viewId.equals(MemoryPage.persistentAllocsViewID)
+ && !viewId.equals(MemoryPage.leaksViewID))
return false;
Object obj = selData.getData();
import org.tizen.dynamicanalyzer.common.Global;
import org.tizen.dynamicanalyzer.model.TableInput;
import org.tizen.dynamicanalyzer.nl.MemoryPageLabels;
-import org.tizen.dynamicanalyzer.ui.memory.MemoryPage;
+import org.tizen.dynamicanalyzer.ui.memory.MemoryPersistentAllocationsTableView;
import org.tizen.dynamicanalyzer.ui.memory.data.HeapDataManager;
import org.tizen.dynamicanalyzer.ui.toolbar.Toolbar;
import org.tizen.dynamicanalyzer.ui.widgets.table.DATableComposite;
import org.tizen.dynamicanalyzer.ui.widgets.table.DATableDataFormat;
import org.tizen.dynamicanalyzer.ui.widgets.table.DefaultTableComparator;
+import org.tizen.dynamicanalyzer.util.Logger;
import org.tizen.dynamicanalyzer.widgets.timeline.MarkerManager;
public class MemoryPersistentAllocationsTable extends DATableComposite {
private Long StartTime;
private Long EndTime;
+ private boolean onlyLeaks;
- public MemoryPersistentAllocationsTable(Composite parent, int style, int tableStyle) {
+ public MemoryPersistentAllocationsTable(Composite parent, int style, int tableStyle,
+ boolean onlyLeaks) {
super(parent, style, tableStyle);
- StartTime = (long)0;
- EndTime = (long)0;
+ StartTime = 0L;
+ EndTime = 0L;
+
+ this.onlyLeaks = onlyLeaks;
setTableName(MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_TITLE);
setComparator(new DefaultTableComparator());
setTableToolTipEnable(false);
// hide 'seq #' column
- table.getColumn(0).setVisible(false);
+ table.getColumn(MemoryPersistentAllocationsTableIndex.SEQ.getIndex()).setVisible(false);
+ if (onlyLeaks)
+ table.getColumn(MemoryPersistentAllocationsTableIndex.LEAK.getIndex())
+ .setVisible(false);
table.addSelectionListener(new SelectionListener() {
Toolbar.INSTANCE.setChartDragStartTime(startTime);
Toolbar.INSTANCE.setChartDragEndTime(endTime);
Toolbar.INSTANCE.setDlogSelection(false);
- DASelectionData data = new DASelectionData(MemoryPage.allocationtraceViewID, startTime,
- endTime, items, table);
+
+ Composite view = table.getParent();
+ while (view != null && !(view instanceof MemoryPersistentAllocationsTableView))
+ view = view.getParent();
+
+ if (view == null) {
+ Logger.warning("Could not find parent view");
+ return;
+ }
+
+ DASelectionData data = new DASelectionData(
+ ((MemoryPersistentAllocationsTableView) view).getID(), startTime, endTime,
+ items, table);
AnalyzerManager.getCurrentPage().updateView(data);
}
if(DAState.isRunning() == false) {
if(StartTime == 0 && EndTime == 0 && Toolbar.INSTANCE.getSelectedPid() <= 0) {
- List<TableInput> wholedata = HeapDataManager.getInstance().getWholeAllocationTraceTreeInput();
+ List<TableInput> wholedata;
+ if (onlyLeaks)
+ wholedata = HeapDataManager.getInstance().getLeaksTableInput();
+ else
+ wholedata = HeapDataManager.getInstance().getPersistentAllocsTableInput();
+
if(wholedata.size() != 0) {
return wholedata;
}
}
List<List<Object>> allocDataList = null;
- String pidliststring = getTargetPIDString();
- allocDataList = HeapDataManager.getInstance().remainedAllocatedListForRange(StartTime, EndTime, pidliststring);
+ allocDataList = HeapDataManager.getInstance().remainedAllocatedListForRange(StartTime,
+ EndTime, onlyLeaks);
if (allocDataList == null || allocDataList.size() == 0)
return output;
for (int j = 0; j < size; j++) {
List<Object> iAllocData = allocDataList.get(j);
- TableInput alloInput = HeapDataManager.getInstance().makeTreeInputForLeakData(iAllocData, index++);
+ TableInput alloInput = HeapDataManager.getInstance()
+ .makePersistentAllocsTableInput(iAllocData, index++, onlyLeaks);
if (alloInput != null){
output.add(alloInput);
}
table.removeAll();
updateTable();
}
-
- private String getTargetPIDString(){
- List<Integer> pidlist = new ArrayList<Integer>();
-
- int[] pids = Global.getProject().getProcessIDs();
- int targetPID = Toolbar.INSTANCE.getSelectedPid();
- if(targetPID > 0) {
- pidlist.add(targetPID);
- }
- else {
- for (int i = 0; i < pids.length; i++) {
- pidlist.add(pids[i]);
- }
- }
-
- String pidliststring = "(";
-
- for(int i = 0 ; i < pidlist.size() ; i++) {
- pidliststring += Integer.toString(pidlist.get(i));
-
- if(i != pidlist.size() - 1) {
- pidliststring += ", ";
- }
- }
-
- pidliststring += ")";
-
- return pidliststring;
- }
-
@Override
public void clear() {
table.removeAll();
MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_LIBRARY),
CALLED(7, 115, AnalyzerConstants.SORT_TYPE_STRING, SWT.CENTER,
MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_CALLED_FUNCTION),
- LEAK(8, 60, AnalyzerConstants.SORT_TYPE_GRID, SWT.RIGHT,
+ LEAK(8, 60, AnalyzerConstants.SORT_TYPE_GRID, SWT.CENTER,
MemoryPageLabels.MEMORY_ALLOCATION_TRACE_VIEW_LEAK);
// @formatter:on
private MenuItem fileNew;
private MenuItem viewDetail;
private MenuItem analyzeSearchItem;
- private MenuItem viewPersistentMemoryCharts;
+ private MenuItem viewPersistentAllocations;
public MenuItem getFileNew() {
return fileNew;
}
/**
- * Returns selection of 'Persistent Memory Charts' {@link MenuItem}.
+ * Returns selection of 'Persistent Allocations' {@link MenuItem}.
*
* @return {@code true} if selected.
*/
- public boolean getPersistentMemoryChartsSelection() {
- if (viewPersistentMemoryCharts != null)
- return viewPersistentMemoryCharts.getSelection();
+ public boolean getPersistentAllocationsSelection() {
+ if (viewPersistentAllocations != null)
+ return viewPersistentAllocations.getSelection();
return false;
}
viewReportWarning.setText(MenuBarLabels.VIEW_WARNING);
viewReportWarning.addSelectionListener(viewReportMenuListener);
- viewPersistentMemoryCharts = new MenuItem(viewReportMenu, SWT.CHECK);
- viewPersistentMemoryCharts.setText(MenuBarLabels.VIEW_PERSISTENT_MEMORY);
- viewPersistentMemoryCharts.addSelectionListener(viewReportMenuListener);
+ viewPersistentAllocations = new MenuItem(viewReportMenu, SWT.CHECK);
+ viewPersistentAllocations.setText(MenuBarLabels.VIEW_PERSISTENT_ALLOCATIONS);
+ viewPersistentAllocations.addSelectionListener(viewReportMenuListener);
MenuItem viewNavigate = new MenuItem(viewMenu, SWT.CASCADE);
viewNavigate.setText(MenuBarLabels.VIEW_NAVIGATE);
}
tableView.removeView(WarningDataView.class.getName(), false);
}
- } else if (menuName.equals(MenuBarLabels.VIEW_PERSISTENT_MEMORY)) {
+ } else if (menuName.equals(MenuBarLabels.VIEW_PERSISTENT_ALLOCATIONS)) {
+ boolean selected = source.getSelection();
+
MemoryChartView chartView = (MemoryChartView) AnalyzerUtil.getView(MemoryPage.pageID,
MemoryChartView.class.getName());
+ // show the charts
if (chartView != null) {
- ((MemoryChartBoard) chartView.getChartBoard()).showPersistentSeries(source.getSelection());
+ ((MemoryChartBoard) chartView.getChartBoard()).showPersistentSeries(selected);
chartView.updateView();
}
+
+ // show the table
+ MemoryPage memoryPage = (MemoryPage) AnalyzerUtil.getTabPage(MemoryPage.pageID);
+ if (memoryPage != null) {
+ memoryPage.showPersistentAllocationsView(selected);
+ memoryPage.updateView();
+ }
}
((TimelinePage)AnalyzerUtil.getTabPage(TimelinePage.pageID)).resizeTableButton();
}
protected void upEvent() {\r
int index = itemIndex + selection;\r
\r
- if (index > -1 && index < getItems().size()) {\r
- setTextAndID(\r
- items.get(itemIndex + selection),\r
- itemIDs.get(itemIndex + selection));\r
- } else {\r
- Logger.debug("Combo index bug [%d]", index);\r
- }\r
-\r
if (childShell != null) {\r
childShell.close();\r
}\r
childShell = null;\r
+\r
+ // index < 0 (-1) denotes empty selection\r
+ if (index < 0) {\r
+ return;\r
+ }\r
+\r
+ // index out of bound denotes some indexing error\r
+ if (index >= getItems().size()) {\r
+ Logger.debug("Combo indexing error: [%d]", index);\r
+ return;\r
+ }\r
+\r
+ setTextAndID(items.get(index), itemIDs.get(index));\r
}\r
\r
private Listener popupMouseEventListener = new Listener() {\r
}
Global.setCurrentApplication(selectedApp);
- curDev.setSelectedAppID(selectedApp.getAppID());
onAppSelected(selectedApp);
} else {
updateAppCombo(false);
Global.setCurrentApplication(null);
if (curDev != null) {
onAppSelected(null);
- curDev.setSelectedAppID(null);
}
bret = true;
// copy binaries
onAppSelected(selectedApp);
- curDev.setSelectedAppID(appID);
bret = true;
}
import org.tizen.dynamicanalyzer.setting.SettingDataManager;
import org.tizen.dynamicanalyzer.shortcut.ShortCutManager;
import org.tizen.dynamicanalyzer.ui.memory.MemoryPage;
-import org.tizen.dynamicanalyzer.ui.memory.MemoryPersistentAllocationsTableView;
import org.tizen.dynamicanalyzer.ui.page.MenuBar;
import org.tizen.dynamicanalyzer.utils.AnalyzerUtil;
import org.tizen.dynamicanalyzer.widgets.button.DACustomButton;
SettingDataManager.INSTANCE.setPreferenceSelected(FlatPreferences.LEAK_SANITIZER,
leakSanitizerToggle.isToggled());
- ((MemoryPersistentAllocationsTableView) AnalyzerUtil
- .getView(MemoryPage.pageID, MemoryPersistentAllocationsTableView.ID))
- .updateView();
+ MemoryPage memoryPage = (MemoryPage) AnalyzerUtil.getTabPage(MemoryPage.pageID);
+ if (memoryPage != null) {
+ memoryPage.showLeaksView(leakSanitizerToggle.isToggled());
+ memoryPage.updateView();
+ }
}
private DACustomCombo makeDACustomCombo(Composite parent, String unit) {
// create button toggles for every app in the list
for (Entry<String, AppInfo> elem : flatAppMapByID.entrySet()) {
AppInfo appInfo = elem.getValue();
+ // don't process special applications
+ if (appInfo.isSpecialApp())
+ continue;
DACustomFeatureToggleButton toggle = createToggleButton(appListComp,
appInfo.getLabel(),
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
-import org.tizen.dynamicanalyzer.common.AnalyzerConstants;
-import org.tizen.dynamicanalyzer.common.AnalyzerShellCommands;
-import org.tizen.dynamicanalyzer.communicator.CommunicatorUtils;
+import org.tizen.dynamicanalyzer.communicator.DACommunicator;
import org.tizen.dynamicanalyzer.communicator.DeviceInfo;
import org.tizen.dynamicanalyzer.communicator.DeviceManager;
-import org.tizen.dynamicanalyzer.control.ApplistManager;
import org.tizen.dynamicanalyzer.nl.ConfigureLabels;
-import org.tizen.dynamicanalyzer.project.AppInfo;
-import org.tizen.dynamicanalyzer.project.PackageInfo;
import org.tizen.dynamicanalyzer.resources.ColorResources;
import org.tizen.dynamicanalyzer.resources.FontResources;
import org.tizen.dynamicanalyzer.resources.ImageResources;
import org.tizen.dynamicanalyzer.widgets.button.DACustomButtonClickEventListener;
import org.tizen.dynamicanalyzer.widgets.button.toggle.DACustomFeatureToggleButton;
import org.tizen.dynamicanalyzer.widgets.da.view.DABaseComposite;
-import org.tizen.sdblib.receiver.MultiLineReceiver;
public class TargetDialogTargetPage extends DABaseComposite {
toggleButton.setToggled(true);
toggleButton.getParent().setBackground(ColorResources.FEATURE_FEATURELISTCOMP_SELECT_BACKGROUND);
- targetDialog.getAppListPage().drawAppList(updateAppListFromTarget(curDev));
+ targetDialog.getAppListPage().drawAppList(DACommunicator.updatePkgMapFromTarget(curDev));
targetDialog.getInfoPage().drawDeviceInfoPage(curDev);
return true;
}
return ret;
}
- private Map<String, PackageInfo> updateAppListFromTarget(DeviceInfo curDev) {
- if (curDev == null) {
- return null;
- }
-
- final List<String> unittestLines = new ArrayList<String>();
- final List<String> imeLines = new ArrayList<String>();
- final List<String> pkginfoLines = new ArrayList<String>();
-
- CommunicatorUtils.execShellCommand(curDev.getIDevice(), AnalyzerShellCommands.CMD_APPLICATION_LIST,
- new MultiLineReceiver() {
- @Override
- public void processNewLines(String[] appLines) {
- for (int i = 0; i < appLines.length; i++) {
- pkginfoLines.add(appLines[i]);
- }
- }
- });
-
- pkginfoLines.add("");
-
- // add lines for running process
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "[" + AnalyzerConstants.RUNNING_PROCESS
- + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.RUNNING_PROCESS);
- pkginfoLines.add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.RUNNING_PROCESS);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":" + AnalyzerConstants.RUNNING_PROCESS_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_RUNNING);
- pkginfoLines.add("");
-
- // add lines for common-executable
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "["
- + AnalyzerConstants.COMMON_EXECUTABLE + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.COMMON_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.COMMON_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":" + AnalyzerConstants.COMMON_EXECUTABLE_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_EXEC);
- pkginfoLines.add("");
-
- // add lines for without-executable
- pkginfoLines.add(PackageInfo.PKGTYPE + "[unknown]" + PackageInfo.PKGID + "["
- + AnalyzerConstants.WITHOUT_EXECUTABLE + "]" + PackageInfo.PRELOAD + "[1]");
- pkginfoLines.add(AppInfo.PROPERTY.APPID.name + ":" + AnalyzerConstants.WITHOUT_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.PACKAGE.name + ":" + AnalyzerConstants.WITHOUT_EXECUTABLE);
- pkginfoLines.add(AppInfo.PROPERTY.LABEL.name + ":" + AnalyzerConstants.WITHOUT_EXECUTABLE_LABEL);
- pkginfoLines.add(AppInfo.PROPERTY.APPTYPE.name + ":" + AppInfo.APPTYPE_NONE);
- pkginfoLines.add("");
-
- curDev.updatePackageList(ApplistManager.parseTizenPkginfo(pkginfoLines, unittestLines, imeLines,
- curDev.getIDevice().getAppInstallPath()));
-
- return curDev.getPackageInfoMap();
- }
-
private Listener toggleUpListener = new Listener() {
public void handleEvent(Event event) {
DACustomFeatureToggleButton toggleButton = (DACustomFeatureToggleButton) event.widget;
String serial = device.getIDevice().getSerialNumber();
if (serial.equals(toggleButton.getToolTipText())) {
if (toggleButton.isToggled()) {
- targetDialog.getAppListPage().drawAppList(updateAppListFromTarget(device));
+ targetDialog.getAppListPage().drawAppList(
+ DACommunicator.updatePkgMapFromTarget(device));
targetDialog.getInfoPage().drawDeviceInfoPage(device);
targetDialog.getInfoPage().drawAppInfoPage(null);
} else {
import org.eclipse.nebula.widgets.grid.GridColumn;
import org.eclipse.nebula.widgets.grid.GridItem;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyEvent;
me = this;
setTableToolTipListener(new TableTooltipListener(table));
applyFilterImage();
+
DATableRegistry.addTable(this);
+ addDisposeListener(new DisposeListener() {
+ @Override
+ public void widgetDisposed(DisposeEvent e) {
+ DATableRegistry.removeTable(me);
+ }
+ });
}
protected Grid createGrid(int tableStyle) {
isFilter = false;
}
- @Override
- public void dispose() {
- super.dispose();
- DATableRegistry.removeTable(this);
- }
/**
* Propagate table activation to the parent {@link DATabComposite}.
*/
+* 2.4.4
+- Apply a workaround for non-root sdbd
+- Make Persistent Allocations table to be hidden by default
+- Introduce Leaks tables
+- Show leaks in only profiled application binary to be 100% true positive
+- Refactor HeapDataManager to use less memory
+- Fix CLI arguments' descritions to be started with small letter
+- Fix crashes in TargetDialog occured in platform mode
+- Fix bug with creation of multiple tabs with the same view (regression in DA 2.4.0)
+- Fix for Startup table not filled (regression in DA 2.4.0)
+- Fix unit tests failures
+- Remove obsolete methods in DeviceInfo
+- Remove redundant debug message on mouse up in toolbar
+- Remove redundant debug message about app ids
+- Fix JIRA defects:
+ SPTSDKUX-2879: All application package name are cropped.
+ SPTSDKUX-2964: Tracing unable to start second time when select Range during tracing.
* 2.4.3
- Fix chart tooltip redrawing on mouse move event
- Fix View>Report toggles state after trace opening
Source:dynamic-analyzer
-Version:2.4.3
+Version:2.4.4
Maintainer:Gihun Chang <gihun.chang@samsung.com>, WooJin Jung <woojin2.jung@samsung.com>, Jaewon Lim <jaewon81.lim@samsung.com>, Seokgil Kang <seokgil.kang@samsung.com>
Package:dynamic-analyzer-product
<modelVersion>4.0.0</modelVersion>
<groupId>org.tizen.dynamicanalyzer</groupId>
<artifactId>dynamic-analyzer</artifactId>
- <version>2.4.3-SNAPSHOT</version>
+ <version>2.4.4-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
#include "da_0010_memory.h"
-#define ALLOC_SIZE 100
+#define ALLOC_SIZE 1024
+#define ALLOC_CHUNK 128
typedef struct appdata {
Evas_Object *win;
elm_win_lower(ad->win);
}
-static void
-_btn_alloc_clicked_cb(void *data, Evas_Object *obj, void *event_info)
-{
- int i, nByte;
- nByte = 1024;
+void* simple_alloc(int size) {
+ return malloc(size);
+}
- for (i = 0; i <= ALLOC_SIZE-2; i++) {
+void allocate_to_global(int nByte) {
+ int i, k;
+ for (i = 0, k = 0; k <= ALLOC_CHUNK; i++) {
+ if (i >= ALLOC_SIZE) break;
if (allocMem[i]) {
-// LOGD("%s", "already allocated memory !!\n");
continue;
} else {
- allocMem[i] = (char *)malloc(nByte);
-// LOGD("%s", "call malloc() !!\n");
- i++;
- if (allocMem[i] == NULL) {
- allocMem[i] = (char *)calloc(nByte, 1);
-// LOGD("%s", "call calloc() !!\n");
- }
+ allocMem[i] = (char*) simple_alloc(nByte);
+ k++;
}
}
}
static void
+_btn_alloc_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ int nByte = 2048;
+
+ data = simple_alloc(100); // never deallocate - memory leak!
+
+ allocate_to_global(nByte);
+}
+
+static void
_btn_free_clicked_cb(void *data, Evas_Object *obj, void *event_info)
{
- for (int i = 0; i < ALLOC_SIZE; i++) {
+ int i, k;
+ for (i = 0, k = 0; k < ALLOC_CHUNK; i++) {
+ if (i >= ALLOC_SIZE) break;
if (allocMem[i]) {
free(allocMem[i]);
allocMem[i] = NULL;
-// LOGD("%s", "free memory !!\n");
+ k++;
}
}
}
ad->allocButton = elm_button_add(ad->win);
elm_object_text_set(ad->allocButton, "Memory Allocation");
evas_object_move(ad->allocButton, 120, 100);
- evas_object_resize(ad->allocButton, 250, 50);
+ evas_object_resize(ad->allocButton, 450, 50);
evas_object_show(ad->allocButton);
ad->freeButton = elm_button_add(ad->win);
elm_object_text_set(ad->freeButton, "Memory Free");
evas_object_move(ad->freeButton, 120, 170);
- evas_object_resize(ad->freeButton, 250, 50);
+ evas_object_resize(ad->freeButton, 450, 50);
evas_object_show(ad->freeButton);
ad->exitButton = elm_button_add(ad->win);
elm_object_text_set(ad->exitButton, "Exit");
evas_object_move(ad->exitButton, 120, 240);
- evas_object_resize(ad->exitButton, 250, 50);
+ evas_object_resize(ad->exitButton, 450, 50);
evas_object_show(ad->exitButton);
evas_object_smart_callback_add(ad->allocButton, "clicked", _btn_alloc_clicked_cb, NULL);
ui_app_lifecycle_callback_s event_callback = {0,};
app_event_handler_h handlers[5] = {NULL, };
- // add malloc() for test
- void *a = malloc(4);
-
- void *b = realloc(a, 8);
-
init();
event_callback.create = app_create;
ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
ui_app_remove_event_handler(handlers[APP_EVENT_LOW_MEMORY]);
- // add malloc() for test
- void *c = malloc(16);
-
ret = ui_app_main(argc, argv, &event_callback, &ad);
if (ret != APP_ERROR_NONE) {
dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);