The standard way would be the following:
if (ptrace(PTRACE_TRACEME, 0, NULL, 0) == -1)
printf("traced!\n");
In this case ptrace returns an error if the current process is traced (i.e. running it with gdb or attaching to it).
But there is a serious problem with this: if the call returns successfully, gdb may not attach to it later. Which is a problem since I'm not trying to implement anti-debug stuff. My purpose is to emit an 'int 3' when a contition is met (i.e. an assert fails) and gdb is running (otherwise I get a SIGTRAP which stops the application).
Disabling SIGTRAP and emitting an 'int 3' every time is not a good sollution because the application I'm testing might be using SIGTRAP for some other purpose (in which case I'm still screwed, so it wouldn't matter but it's the principle of the thing :))
Thanks
Ранее в качестве комментария: вы могли разветвить дочерний элемент, который попытался бы PTRACE_ATTACH
своего родителя (а затем при необходимости отсоединить) и сообщить результат обратно. Хотя это кажется немного неэлегантным.
Как вы упомянули, это довольно дорого. Я думаю, это не так уж плохо, если утверждения терпят неудачу нерегулярно. Возможно, было бы целесообразно сохранить для этого один долго работающий дочерний элемент — совместно использовать два канала между родителем и дочерним элементом, дочерний элемент выполняет свою проверку, когда читает байт, а затем отправляет байт обратно со статусом.
Код В итоге я использовал следующее:
int
gdb_check()
{
int pid = fork();
int status;
int res;
if (pid == -1)
{
perror("fork");
return -1;
}
if (pid == 0)
{
int ppid = getppid();
/* Child */
if (ptrace(PTRACE_ATTACH, ppid, NULL, NULL) == 0)
{
/* Wait for the parent to stop and continue it */
waitpid(ppid, NULL, 0);
ptrace(PTRACE_CONT, NULL, NULL);
/* Detach */
ptrace(PTRACE_DETACH, getppid(), NULL, NULL);
/* We were the tracers, so gdb is not present */
res = 0;
}
else
{
/* Trace failed so gdb is present */
res = 1;
}
exit(res);
}
else
{
waitpid(pid, &status, 0);
res = WEXITSTATUS(status);
}
return res;
}
Несколько моментов:
В любом случае, спасибо за ответы.
Если вы просто хотите узнать, работает ли приложение под gdb
для отладки Для целей Linux самым простым решением является readlink("/proc/
и поиск результата для "gdb"
.