Оконные функции - ваш друг (требуется 3.25 или новее):
SELECT user, score
FROM (SELECT user, score,
row_number() OVER (PARTITION BY user ORDER BY score DESC) AS rn
FROM test)
WHERE rn <= 3
ORDER BY user, score DESC;
Если функции не встраиваются, у Вас могла бы даже быть удача с помощью objdump -d <program>
.
Для примера давайте возьмем ограбление в начале GCC 4.3.2's main
стандартная программа:
$ objdump `which gcc` -d | grep '\(call\|main\)'
08053270 <main>:
8053270: 8d 4c 24 04 lea 0x4(%esp),%ecx
--
8053299: 89 1c 24 mov %ebx,(%esp)
805329c: e8 8f 60 ff ff call 8049330 <strlen@plt>
80532a1: 8d 04 03 lea (%ebx,%eax,1),%eax
--
80532cf: 89 04 24 mov %eax,(%esp)
80532d2: e8 b9 c9 00 00 call 805fc90 <xmalloc_set_program_name>
80532d7: 8b 5d 9c mov 0xffffff9c(%ebp),%ebx
--
80532e4: 89 04 24 mov %eax,(%esp)
80532e7: e8 b4 a7 00 00 call 805daa0 <expandargv>
80532ec: 8b 55 9c mov 0xffffff9c(%ebp),%edx
--
8053302: 89 0c 24 mov %ecx,(%esp)
8053305: e8 d6 2a 00 00 call 8055de0 <prune_options>
805330a: e8 71 ac 00 00 call 805df80 <unlock_std_streams>
805330f: e8 4c 2f 00 00 call 8056260 <gcc_init_libintl>
8053314: c7 44 24 04 01 00 00 movl $0x1,0x4(%esp)
--
805331c: c7 04 24 02 00 00 00 movl $0x2,(%esp)
8053323: e8 78 5e ff ff call 80491a0 <signal@plt>
8053328: 83 e8 01 sub $0x1,%eax
Это прилагает немного усилий для прохождения через весь ассемблер, но Вы видите все возможные вызовы от заданной функции. Это не столь просто в использовании как gprof
или некоторые из других утилит упомянули, но это имеет несколько явных преимуществ:
gprof
только покажет выполняемые вызовы функции.Существует скрипт оболочки для автоматизации вызова функций трассировки с помощью gdb. Но он не может быть прикреплен к запущенному процессу.
blog.superadditive.com/2007/12/01/call-graphs-using-the-gnu-project-debugger/
Копия страницы - http://web.archive.org/web/20090317091725/http://blog.superadditive.com/2007/12/01/call-graphs-using-the-gnu-project-debugger/
Копия инструмента - callgraph.tar.gz
http://web.archive.org/web/20090317091725/http://superadditive.com/software/callgraph.tar.gz
Он сбрасывает все функции из программы и генерирует командный файл gdb с точками останова на каждой функции. В каждой точке останова выполняются "backtrace 2" и "continue".
Этот скрипт довольно медленно работает на большом порте (~ тысячах функций), поэтому я добавляю фильтр в список функций (через egrep). Это было очень просто, и я использую этот скрипт почти каждый день
.