1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 17:35:35 +02:00

debug tests: Add test for thread name

This patch adds SyncUtil.getThreadData to make it easy to get the thread
data from the gdb thread number.

Change-Id: I948a8b87cc3afa64f3d73de23d4ace12ef4c0c1a
Signed-off-by: Simon Marchi <simon.marchi@polymtl.ca>
Reviewed-on: https://git.eclipse.org/r/36870
Reviewed-by: Alvaro Sanchez-Leon <alvsan09@gmail.com>
Tested-by: Alvaro Sanchez-Leon <alvsan09@gmail.com>
This commit is contained in:
Simon Marchi 2014-11-21 16:59:55 -05:00 committed by Alvaro Sanchez-Leon
parent daa20f98b4
commit 79c6c7d775
5 changed files with 66 additions and 52 deletions

View file

@ -11,6 +11,7 @@ struct PrintHelloArgs {
ThreadBarrier *barrier_start;
ThreadBarrier *barrier_finish;
ThreadSemaphore *sem_start;
const char *name;
};
static ThreadRet THREAD_CALL_CONV PrintHello(void *void_arg)
@ -20,12 +21,15 @@ static ThreadRet THREAD_CALL_CONV PrintHello(void *void_arg)
ThreadBarrier *barrier_start = args->barrier_start;
ThreadBarrier *barrier_finish = args->barrier_finish;
ThreadSemaphore *sem_start = args->sem_start;
const char *name = args->name;
/* Indicate to main thread that the thread is started. */
ThreadSemaphorePut(sem_start);
printf("Hello World! It's me, thread #%d!\n", thread_id);
ThreadSetName(name);
/* Make sure that all threads are started before the breakpoint in main hits. */
ThreadBarrierWait(barrier_start);
@ -43,6 +47,7 @@ int main(int argc, char *argv[])
{
ThreadHandle threads[NUM_THREADS];
struct PrintHelloArgs args[NUM_THREADS];
const char *thread_names[NUM_THREADS] = {"monday", "tuesday", "wednesday", "thursday", "friday"};
/* Used to make rendez-vous points between all threads. */
ThreadBarrier barrier_start;
@ -65,10 +70,11 @@ int main(int argc, char *argv[])
args[t].barrier_start = &barrier_start;
args[t].barrier_finish = &barrier_finish;
args[t].sem_start = &sem_start;
args[t].name = thread_names[t];
int ret = StartThread(PrintHello, &args[t], &threads[t]);
int ret = StartThread(PrintHello, &args[t], &threads[t]); /* Breakpoint LINE_MAIN_BEFORE_THREAD_START */
if (!ret)
if (!ret) /* Breakpoint LINE_MAIN_AFTER_THREAD_START */
{
printf("Error: StartThread failed.\n");
exit(-1);
@ -83,7 +89,7 @@ int main(int argc, char *argv[])
/* Let the threads continue to the 'critical' section> */
ThreadBarrierWait(&barrier_start);
printf("In main thread, all threads created.\n"); /* main breakpoint here */
printf("In main thread, all threads created.\n"); /* Breakpoint LINE_MAIN_ALL_THREADS_STARTED */
SLEEP(30);

View file

@ -2,8 +2,7 @@
#define THREADPTHREAD_H
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
/* Thread functions */
@ -55,4 +54,9 @@ static int ThreadSemaphoreDestroy(ThreadSemaphore *sem)
return sem_destroy(sem) == 0;
}
static int ThreadSetName(const char *name)
{
return prctl(PR_SET_NAME, name, 0, 0, 0) == 0;
}
#endif // THREADPTHREAD_H

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007, 2014 Ericsson and others.
* Copyright (c) 2007, 2015 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* Ericsson AB - Initial implementation of Test cases
* Alvaro Sanchez-Leon (Ericsson) - Bug 437562 - Split the dsf-gdb tests to a plug-in and fragment pair
* Simon Marchi (Ericsson) - Make canRestart and restart throw Exception instead of Throwable.
* Simon Marchi (Ericsson) - Add getThreadData.
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.framework;
@ -43,6 +44,7 @@ import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.IFormattedDataDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IContainerDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExecutionDMContext;
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
@ -480,6 +482,26 @@ public class SyncUtil {
return query.get(500, TimeUnit.MILLISECONDS);
}
public static IThreadDMData getThreadData(final int threadId)
throws InterruptedException, ExecutionException, TimeoutException {
final IProcessDMContext processContext = DMContexts.getAncestorOfType(
SyncUtil.getContainerContext(), IProcessDMContext.class);
Query<IThreadDMData> query = new Query<IThreadDMData>() {
@Override
protected void execute(DataRequestMonitor<IThreadDMData> rm) {
IThreadDMContext threadDmc = fProcessesService
.createThreadContext(processContext,
Integer.toString(threadId));
fProcessesService.getExecutionData(threadDmc, rm);
}
};
fSession.getExecutor().execute(query);
return query.get(500, TimeUnit.MILLISECONDS);
}
public static IExpressionDMContext createExpression(final IDMContext parentCtx, final String expression)
throws Throwable {
Callable<IExpressionDMContext> callable = new Callable<IExpressionDMContext>() {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2009, 2014 Ericsson and others.
* Copyright (c) 2009, 2015 Ericsson and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,7 +7,7 @@
*
* Contributors:
* Ericsson AB - Initial implementation of Test cases
* Simon Marchi (Ericsson) - Check for thread name support.
* Simon Marchi (Ericsson) - Check for thread name support, add thread name test.
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
@ -25,7 +25,6 @@ import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.mi.service.IMIProcesses;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
@ -49,7 +48,7 @@ public class GDBProcessesTest extends BaseTestCase {
* Name of the executable
*/
private static final String EXEC_NAME = "MultiThread.exe";
private static final String SOURCE_NAME = "MultiThread.cc";
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
@ -152,46 +151,28 @@ public class GDBProcessesTest extends BaseTestCase {
* getThreadData() for multiple threads
*/
@Test
public void getThreadData() throws InterruptedException, ExecutionException, TimeoutException {
final String THREAD_ID = "1";
final DataRequestMonitor<IThreadDMData> rm =
new DataRequestMonitor<IThreadDMData>(fSession.getExecutor(), null) {
@Override
protected void handleCompleted() {
if (isSuccess()) {
fWait.setReturnInfo(getData());
}
fWait.waitFinished(getStatus());
}
};
public void getThreadData() throws Throwable {
// Start all threads, stop when they are all started
SyncUtil.runToLine(SOURCE_NAME, MIRunControlTest.LINE_MAIN_ALL_THREADS_STARTED);
IThreadDMData mainThreadData = SyncUtil.getThreadData(1);
final IProcessDMContext processContext = DMContexts.getAncestorOfType(SyncUtil.getContainerContext(), IProcessDMContext.class);
fProcService.getExecutor().submit(new Runnable() {
@Override
public void run() {
IThreadDMContext threadDmc = fProcService.createThreadContext(processContext, THREAD_ID);
fProcService.getExecutionData(threadDmc, rm);
}
});
// Test that thread id is only a series of numbers
Pattern pattern = Pattern.compile("\\d*", Pattern.MULTILINE); //$NON-NLS-1$
Matcher matcher = pattern.matcher(mainThreadData.getId());
assertTrue("Thread ID is a series of number", matcher.matches());
// Wait for the operation to complete and validate success.
fWait.waitUntilDone(TestsPlugin.massageTimeout(2000));
assertTrue(fWait.getMessage(), fWait.isOK());
IThreadDMData threadData = (IThreadDMData)fWait.getReturnInfo();
Assert.assertNotNull("Thread data not returned for thread id = " + THREAD_ID, threadData);
// Check the thread names. We did not change the main thread's name, so
// it should be the same as the executable name.
final String names[] = { EXEC_NAME, "monday", "tuesday", "wednesday",
"thursday", "friday" };
// Thread id is only a series of numbers
Pattern pattern = Pattern.compile("\\d*", Pattern.MULTILINE); //$NON-NLS-1$
Matcher matcher = pattern.matcher(threadData.getId());
assertTrue("Thread ID is a series of number", matcher.find());
// Check thread name
String expectedThreadName = threadNamesSupported() ? EXEC_NAME : "";
assertEquals("main thread's name is wrong", expectedThreadName, threadData.getName());
fWait.waitReset();
// Check that we have correct data for PrintHello
for (int i = 1; i <= 6; i++) {
IThreadDMData threadData = SyncUtil.getThreadData(i);
String name = threadData.getName();
String expectedName = threadNamesSupported() ? names[i - 1] : "";
assertEquals("Thread name of thread " + i, expectedName, name);
}
}
}

View file

@ -9,6 +9,7 @@
* Ericsson AB - Initial implementation of Test cases
* Simon Marchi (Ericsson) - Add and use runningOnWindows().
* Simon Marchi (Ericsson) - Adapt test code to thread platform compatibility layer.
* Simon Marchi (Ericsson) - Change breakpoint line numbers.
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
@ -85,21 +86,21 @@ public class MIRunControlTest extends BaseTestCase {
private IExecutionDMContext fThreadExecDmc;
// line numbers in MultiThread.cc
static final int LINE_MAIN_BEFORE_THREAD_START = 69; // Just before StartThread
static final int LINE_MAIN_AFTER_THREAD_START = 80; // Just after StartThread, where the thread is guaranteed to be started.
static final int LINE_MAIN_ALL_THREADS_STARTED = 88; // Where all threads are guaranteed to be started.
static final int LINE_MAIN_BEFORE_THREAD_START = 75; // Just before StartThread
static final int LINE_MAIN_AFTER_THREAD_START = 86; // Just after StartThread, where the thread is guaranteed to be started.
static final int LINE_MAIN_ALL_THREADS_STARTED = 92; // Where all threads are guaranteed to be started.
/*
* Path to executable
*/
private static final String EXEC_PATH = "data/launch/bin/";
/*
* Name of the executable
*/
private static final String EXEC_NAME = "MultiThread.exe";
private static final String SOURCE_NAME = "MultiThread.cc";
@Override
public void doBeforeTest() throws Exception {
super.doBeforeTest();