Break on memory access command - ba command - is very useful for this kind of case. ba allows us to see who is touching the variable. To simplify the case and demonstrate it easily, I will use notepad.exe in WinDBG.
1) Run notepad.exe from WinDBG
C> Windbg notepad.exe
2) Run notepad.exe until you see UI by typing "g"
3) Pause notepad process in windbg
4) In Windbg, check any global variable of notepad process
0:000> x notepad!g_* 00000000`ff6f0050 notepad!g_fFontSettingChanged =00000000`ff6f0b28 notepad!g_fUISettingChanged = 00000000`ff6f0200 notepad!g_PageSetupDlg = 00000000`ff6f1e70 notepad!g_lExisting = 00000000`ff6f2720 notepad!g_ftSaveAs = 00000000`ff6f0b2c notepad!g_fPageSetupChanges = 00000000`ff6f0100 notepad!g_wpOrig = 00000000`ff6f0088 notepad!g_ftOpenedAs =
Here let's pick a variable (notepad!g_ftOpenedAs).
5) Set breakpoint with ba command.
0:001> ba w4 notepad!g_ftOpenedAs ".echo ******; ~. ; kp; g;"
ba command will break into debugger when the specified memory is accessed by any thread / any function. w4 means the debugger will break into if any method is writing to the specificed memory area. second parameter notepad!g_ftOpenedAs is the memory location to watch. And the last parameter is the command that will run when break occurs. If no command is specified, it will break into the debugger and wait at prompt. The command is (1)first print six asterisks, (2) show current thread (~.), (3) show current thread call stack (kp), (4) keep running without break into debugger (g).
6) Run notepad process again ("g")
7) In notepad UI, click File->Open. In Open File Dialog, click Cancel.
This is to let a thread to write a value to global variable.
8) Now, you can see who is touching notepad!g_ftOpenedAs variable by look at the call stack output.
****** . 0 Id: 1290.dbc Suspend: 1 Teb: 000007ff`fffdd000 Unfrozen Start: notepad!WinMainCRTStartup (00000000`ff6e3570) Priority: 0 Priority class: 32 Affinity: f Child-SP RetAddr Call Site 00000000`0019f7b0 00000000`ff6e14eb notepad!NPCommand+0x3fa 00000000`0019f8e0 00000000`77b8c3c1 notepad!NPWndProc+0x540 00000000`0019f920 00000000`77b8c60a USER32!UserCallWinProcCheckWow+0x1ad 00000000`0019f9e0 00000000`ff6e10bc USER32!DispatchMessageWorker+0x3b5 00000000`0019fa60 00000000`ff6e133c notepad!WinMain+0x16f 00000000`0019fae0 00000000`77a6f56d notepad!DisplayNonGenuineDlgWorker+0x2da 00000000`0019fba0 00000000`77ca2cc1 kernel32!BaseThreadInitThunk+0xd 00000000`0019fbd0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d
If you're in live debug mode, you can simply break into the debugger to look into suspicious thread.