Forum Discussion

RandomClear's avatar
RandomClear
New Contributor
9 years ago
Solved

Detect running under AQTime? Avoid crashing debugging code

I usePerformance Profiler in AQTime. Trying to run it under IDE (using Embarcadero RAD Studio XE). Inspected project crashes on such code:

 

 

// Setting a Thread Name (Unmanaged):
// http://msdn.microsoft.com/en-us/library/xcb2z8hs(VS.71).aspx
procedure _NameThreadForDebugging(const ATID: Cardinal; const AThreadName: String);
type
  TThreadNameInfo = record
    FType: LongWord;     // must be 0x1000
    FName: PAnsiChar;    // pointer to name (in user address space)
    FThreadID: LongWord; // thread ID (-1 indicates caller thread)
    FFlags: LongWord;    // reserved for future use, must be zero
  end;
var
  ThreadNameInfo: TThreadNameInfo;
  ThreadName: AnsiString;
begin
  // Applicable only for debugged applications
  if IsDebuggerPresent then
  begin
    FillChar(ThreadNameInfo, SizeOf(ThreadNameInfo), 0);

    ThreadName := AnsiString(AThreadName);
    ThreadNameInfo.FType := $1000;
    ThreadNameInfo.FName := PAnsiChar(ThreadName);
    ThreadNameInfo.FThreadID := ATID;

    try
      RaiseException(cSetThreadNameExcep, 0, SizeOf(ThreadNameInfo) div SizeOf(LongWord), @ThreadNameInfo);
    except
    end;
    Finalize(ThreadName);
  end;
end;

It works fine when run outside of IDE (in which case the routine will exit without doing anything), or when run under usual IDE debugger (in which case the routine will raise exception, which will be handled by IDE's debugger). 

 

 

However, when run under AQTime - the routine will crash right at call to kernel32.RaiseException routine (APPCRASH C00001A5 somewhere inside kernel32). I have confirmed this by putting MessageBoxes around this call (try/except block).

 

Apparently, IsDebuggerPresent is True when run under AQTime, but exception is not properly handled.

 

Question: how can I detect and avoid this? How can I check if code is executed under AQTime?

  • You can check the following environment variables that are passed to the profiled process by default: AQTIME_DEBUGGER_PRESENT and AQTIME_VERSION.

2 Replies