Debugging and tracing thread creation in C and Java on the Windows OS


The introduction of multi core processor computers has spawned a intense argument on the virtues of designating and  implementing concurrent programs utilizing threads and synchronization.


Even so, in the java domain , and in particular, java server side containers and servers,  multi-threaded programming is still a regular pattern for writing concurrent  software.  


More and more vendors have opted to use the java.util.concurrent library or one of its variants (see: ), in order to implement their support for multi-threaded programs.

As a consequence, there is a steep decent in the number of Employers incorporating questions about threads as part of their screening process which brings us to the topic of this post.


A collogue who has just graduated attended a java job interview and was presented with the following questions:

1.       Given a running java process, how can you list the threads owned by the process?

2.       Can you suggest a way to prove that creating a Java thread will create a native OS thread and if not prove otherwise?  

We can answer the first question (which is NOT the focal of this post) by running either VisualVM, jstat or programmatically (if at all possible inside the jvm) using JMX.  But hold your horses before attempting to answer the second question ...  let's get back to the first question ...

1.       Using jstak: once you have the PID of the process (for instance using jps), you can use jstack ( to generate a thread dump:

jstack [-l] <pid>

Note that I “piped” the result into a file for postmortem analysis. Also note that in case of a deadlock the following text will be printed out: “Found <n> Java-level deadlock: “ where <n> is the number of deadlock detected.

2.       using VisualVM: attach to the JVM process and click the “Thread dump” button to generate a thread dump on the fly:

3.       Using JMX: invoke getThreadCount() on the ThreadMXBean  interface which returns the current number of live threads including both daemon and non-daemon threads:

For more information see:  

Creating threads in java:

Before discussing Java thread creation, let's see how thread are created on a native OS such as Windows. We shall get back to java soon after.


Creating a native Windows OS thread using C:

In order to answer question #2 we shall contemplate  the issue of the creation of native OS threads from the JVM  using a minimalistic program which will demonstrate the creation and concurrent execution of threads using the Windows API C method CreateThread().


From the documentation (see : know exactly where this method is implemented, it is under nt32.dll. We could easily set a breakpoint on that DLL and answer the question bare with me and but more on that later. Even so let's write a program and debug it to trace the call to the DLL, then we can see if the same chain of events takes place under java and answer the question.  


I used CodeBlock, which is an open source, cross platform, free C++ IDE available from alongside the GNU C/C++ tool-chain:



The Win32 API method signature for new thread creation is:

//Creates a thread that will run threadMthood concurrently with the main thread.
    threadHandle = CreateThread(NULL,           // pointer to security attributes
                                0,              // initial thread stack size
                                threadMthood,   // pointer to thread function
                                intPtr,         // argument for new thread
                                0,              // creation flags
                                &threadID);     // pointer to receive thread ID

    //After successful invocation, CreateThread returns immediately and threadMthood begins to run


lets view the source code for the whole program which is heavily documented:

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//#include <system.h>
#define MAX_THREADS 3

DWORD WINAPI threadMthood(LPVOID threadArgument)
    int actualVal;
	actualVal = *(int *)threadArgument;
	fprintf(stderr,"Argument is: %d\n",actualVal);
	return NULL;

int main()
    printf("Hello tikal\n");

    int i=99;//magic number
	int *intPtr;
	HANDLE threadHandle;
	DWORD threadID;
	DWORD waitRetVal;

    intPtr = (int *)malloc(sizeof(int));
    *intPtr = i;
    //Creates a thread that will run threadMthood concurrently with the main thread.
    threadHandle = CreateThread(NULL,           // pointer to security attributes
                                0,              // initial thread stack size
                                threadMthood,   // pointer to thread function
                                intPtr,         // argument for new thread
                                0,              // creation flags
                                &threadID);     // pointer to receive thread ID

    //After successful invocation, CreateThread returns immediately and threadMthood begins to run
    if (threadHandle == NULL) {
        fprintf(stderr,"Could not create Thread\n");
    else {
        printf("Thread %d was created\n",threadID);

    printf("Wait for the child thread to terminate...\n");
    //Waits until the specified object is in the signaled state
    //or the time-out interval elapses.
    //INFINITE means the function will return only when the object is signaled.
    waitRetVal = WaitForSingleObject(threadHandle,INFINITE);
    printf("WaitForSingleObject() return value is %d\n", waitRetVal);

    // Close the handle to the thread
    // Closing the thread handle does NOT terminate the thread.
    if(CloseHandle(threadHandle) != 0) {
            printf("Child thread handle was successfully closed\n");
    else {
        printf("Failed to close child thread handle: reason %u\n", GetLastError());
	return 0;


The output for executing Test123.exe is:


Now, assuming we only have the executable, how do we actually trace the call to nt32.dll? There are several ways to accomplish that:


1- Use an analyzer such as PEiD ( which is a GUI-based program that identifies more than 600 different signatures in PE files. Let's use it.


Open the executable and click the "Win 32 console arrow" 


You will be prompted with the "PE details" window, from there select the "ImportTable" option and you will be prompted with a forth window ... which will provide us with the information we need:  



As evident from the GUI  we can see that our C executable is using the KERNEL32.DLL and we can even see the exact address offset of the CreateThread method inside the DLL.


2- What would you do in order to see when and where the CreateThread is invoked?  simple, we use a debugger/disassembler such as IDA pro ( or OLLYDBG ( Both tools are very frequently used for reverse engineering and malware analysis.  If we open the Test123.exe file using OllyDBG and step through using F8 each line (it's stepping the disassembly which is the actual machine code, in this case X86 assembly instructions).



We can see that at memory address 004013BB, there is a call to CreateTjhread and voila, we almost have our answer.


So ... back to Java:


The following java program creates a very simple thread in java using the Thread class and is self explanatory:



package com.tikalk;


 * Created by IntelliJ IDEA.
 * User: skashani
public class TikalThreads {

    public static void main(String args[]) {
        ThreadMXBean tb = ManagementFactory.getThreadMXBean();
        System.out.println("Current thread count:" + tb.getThreadCount());

        Thread thread = new TikalThread();

        try {
        } catch (InterruptedException ignore) {

    static class TikalThread extends Thread {
        // This method is called when the thread runs
        public void run() {
            System.out.println(" I am a java thread, my name is:" + Thread.currentThread().getName());



Very important note : even if it is possible to debug a java program using any IDE such as intelliJ or Eclipse,  we cannot debug a java program in the sense that we debug a C/C++ program and the reason being that Java is using byte code and a JVM - hence the actual program that needs to be debugged in order to intercept a native Windows API createThread() call is java.exe and NOT the actual class itself.


However, disassembling the java.exe program in a similar fashion as we did with the C program using OLLYDBG is strictly against the law and will invalidate the EULA from oracle, not to mention being at a very high risk for a federal law suit :)


What we can do is attach a tool named procexp.exe (process explorer available here: . The tool, written by Sysinternals (now owned by Microsoft) is part of a series of system tools that are meant to aid in such circumstances.  

Let's use it:

Start by executing the tool - you will see a list of all the processes running on the computer (not including hidden process):



We can see that the java.exe program is running.

Next double click the row associated with PID=6784 and you will be prompted with a new window, next select the "threads" tab and click the thread:



The tool does NOT disassemble the java.exe and hence does not break any law in doing so.

This shows the STACK of the specific thread, and if you look closely you will NOT see a call to createThread(). We do see a call to BaseThreadInitThunk  which normally is the function that calls the thread’s start function (more on this here:


Nevertheless, it will NOT show us the actual chain of events from Java to KERNEL32.DLL, it will only show, as depicted in the above image, what API is being used not when and where. It might have been used prior to running our program, and in any case we can sarcastically conclude that:


We have to break the law if want to pass the job interview :)




Thank you for your interest!

We will contact you as soon as possible.

Send us a message

Oops, something went wrong
Please try again or contact us by email at