memusage.sh 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. #!/bin/bash
  2. # Copyright (C) 1999-2026 Free Software Foundation, Inc.
  3. # This file is part of the GNU C Library.
  4. # The GNU C Library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2.1 of the License, or (at your option) any later version.
  8. # The GNU C Library is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. # Lesser General Public License for more details.
  12. # You should have received a copy of the GNU Lesser General Public
  13. # License along with the GNU C Library; if not, see
  14. # <https://www.gnu.org/licenses/>.
  15. memusageso='@SLIBDIR@/libmemusage.so'
  16. memusagestat='@BINDIR@/memusagestat'
  17. TEXTDOMAIN=libc
  18. # Print usage message.
  19. do_usage() {
  20. printf >&2 $"Try \`%s --help' or \`%s --usage' for more information.\n" memusage memusage
  21. exit 1
  22. }
  23. # Message for missing argument.
  24. do_missing_arg() {
  25. printf >&2 $"%s: option '%s' requires an argument\n" memusage "$1"
  26. do_usage
  27. }
  28. # Print help message
  29. do_help() {
  30. echo $"Usage: memusage [OPTION]... PROGRAM [PROGRAMOPTION]...
  31. Profile memory usage of PROGRAM.
  32. -n,--progname=NAME Name of the program file to profile
  33. -p,--png=FILE Generate PNG graphic and store it in FILE
  34. -d,--data=FILE Generate binary data file and store it in FILE
  35. -u,--unbuffered Don't buffer output
  36. -b,--buffer=SIZE Collect SIZE entries before writing them out
  37. --no-timer Don't collect additional information through timer
  38. -m,--mmap Also trace mmap & friends
  39. -?,--help Print this help and exit
  40. --usage Give a short usage message
  41. -V,--version Print version information and exit
  42. The following options only apply when generating graphical output:
  43. -t,--time-based Make graph linear in time
  44. -T,--total Also draw graph of total memory use
  45. --title=STRING Use STRING as title of the graph
  46. -x,--x-size=SIZE Make graphic SIZE pixels wide
  47. -y,--y-size=SIZE Make graphic SIZE pixels high
  48. Mandatory arguments to long options are also mandatory for any corresponding
  49. short options.
  50. "
  51. printf $"For bug reporting instructions, please see:\\n%s.\\n" \
  52. "@REPORT_BUGS_TO@"
  53. exit 0
  54. }
  55. do_version() {
  56. echo 'memusage @PKGVERSION@@VERSION@'
  57. printf $"Copyright (C) %s Free Software Foundation, Inc.
  58. This is free software; see the source for copying conditions. There is NO
  59. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  60. " "2024"
  61. printf $"Written by %s.
  62. " "Ulrich Drepper"
  63. exit 0
  64. }
  65. # These variables are local
  66. buffer=
  67. data=
  68. memusagestat_args=
  69. notimer=
  70. png=
  71. progname=
  72. tracemmap=
  73. # Process arguments. But stop as soon as the program name is found.
  74. while test $# -gt 0; do
  75. case "$1" in
  76. -V | --v | --ve | --ver | --vers | --versi | --versio | --version)
  77. do_version
  78. ;;
  79. -\? | --h | --he | --hel | --help)
  80. do_help
  81. ;;
  82. --us | --usa | --usag | --usage)
  83. echo $"Syntax: memusage [--data=FILE] [--progname=NAME] [--png=FILE] [--unbuffered]
  84. [--buffer=SIZE] [--no-timer] [--time-based] [--total]
  85. [--title=STRING] [--x-size=SIZE] [--y-size=SIZE]
  86. PROGRAM [PROGRAMOPTION]..."
  87. exit 0
  88. ;;
  89. -n | --pr | --pro | --prog | --progn | --progna | --prognam | --progname)
  90. if test $# -eq 1; then
  91. do_missing_arg $1
  92. fi
  93. shift
  94. progname="$1"
  95. ;;
  96. --pr=* | --pro=* | --prog=* | --progn=* | --progna=* | --prognam=* | --progname=*)
  97. progname=${1##*=}
  98. ;;
  99. -p | --pn | --png)
  100. if test $# -eq 1; then
  101. do_missing_arg $1
  102. fi
  103. shift
  104. png="$1"
  105. ;;
  106. --pn=* | --png=*)
  107. png=${1##*=}
  108. ;;
  109. -d | --d | --da | --dat | --data)
  110. if test $# -eq 1; then
  111. do_missing_arg $1
  112. fi
  113. shift
  114. data="$1"
  115. ;;
  116. --d=* | --da=* | --dat=* | --data=*)
  117. data=${1##*=}
  118. ;;
  119. -u | --un | --unb | --unbu | --unbuf | --unbuff | --unbuffe | --unbuffer | --unbuffere | --unbuffered)
  120. buffer=1
  121. ;;
  122. -b | --b | --bu | --buf | --buff | --buffe | --buffer)
  123. if test $# -eq 1; then
  124. do_missing_arg $1
  125. fi
  126. shift
  127. buffer="$1"
  128. ;;
  129. --b=* | --bu=* | --buf=* | --buff=* | --buffe=* | --buffer=*)
  130. buffer=${1##*=}
  131. ;;
  132. --n | --no | --no- | --no-t | --no-ti | --no-tim | --no-time | --no-timer)
  133. notimer=yes
  134. ;;
  135. -m | --m | --mm | --mma | --mmap)
  136. tracemmap=yes
  137. ;;
  138. -t | --tim | --time | --time- | --time-b | --time-ba | --time-bas | --time-base | --time-based)
  139. memusagestat_args="$memusagestat_args -t"
  140. ;;
  141. -T | --to | --tot | --tota | --total)
  142. memusagestat_args="$memusagestat_args -T"
  143. ;;
  144. --tit | --titl | --title)
  145. if test $# -eq 1; then
  146. do_missing_arg $1
  147. fi
  148. shift
  149. memusagestat_args="$memusagestat_args -s $1"
  150. ;;
  151. --tit=* | --titl=* | --title=*)
  152. memusagestat_args="$memusagestat_args -s ${1##*=}"
  153. ;;
  154. -x | --x | --x- | --x-s | --x-si | --x-siz | --x-size)
  155. if test $# -eq 1; then
  156. do_missing_arg $1
  157. fi
  158. shift
  159. memusagestat_args="$memusagestat_args -x $1"
  160. ;;
  161. --x=* | --x-=* | --x-s=* | --x-si=* | --x-siz=* | --x-size=*)
  162. memusagestat_args="$memusagestat_args -x ${1##*=}"
  163. ;;
  164. -y | --y | --y- | --y-s | --y-si | --y-siz | --y-size)
  165. if test $# -eq 1; then
  166. do_missing_arg $1
  167. fi
  168. shift
  169. memusagestat_args="$memusagestat_args -y $1"
  170. ;;
  171. --y=* | --y-=* | --y-s=* | --y-si=* | --y-siz=* | --y-size=*)
  172. memusagestat_args="$memusagestat_args -y ${1##*=}"
  173. ;;
  174. --p | --p=* | --t | --t=* | --ti | --ti=* | --u)
  175. echo >&2 $"memusage: option \`${1##*=}' is ambiguous"
  176. do_usage
  177. ;;
  178. --)
  179. # Stop processing arguments.
  180. shift
  181. break
  182. ;;
  183. --*)
  184. echo >&2 $"memusage: unrecognized option \`$1'"
  185. do_usage
  186. ;;
  187. *)
  188. # Unknown option. This means the rest is the program name and parameters.
  189. break
  190. ;;
  191. esac
  192. shift
  193. done
  194. # See whether any arguments are left.
  195. if test $# -eq 0; then
  196. echo >&2 $"No program name given"
  197. do_usage
  198. fi
  199. # This will be in the environment.
  200. add_env="LD_PRELOAD=$memusageso"
  201. # Generate data file name.
  202. datafile=
  203. if test -n "$data"; then
  204. datafile="$data"
  205. elif test -n "$png"; then
  206. datafile=$(mktemp -t memusage.XXXXXX) || exit
  207. trap 'rm -f "$datafile"; exit 1' HUP INT QUIT TERM PIPE
  208. fi
  209. if test -n "$datafile"; then
  210. add_env="$add_env MEMUSAGE_OUTPUT=$datafile"
  211. fi
  212. # Set program name.
  213. if test -n "$progname"; then
  214. add_env="$add_env MEMUSAGE_PROG_NAME=$progname"
  215. fi
  216. # Set buffer size.
  217. if test -n "$buffer"; then
  218. add_env="$add_env MEMUSAGE_BUFFER_SIZE=$buffer"
  219. fi
  220. # Disable timers.
  221. if test -n "$notimer"; then
  222. add_env="$add_env MEMUSAGE_NO_TIMER=yes"
  223. fi
  224. # Trace mmap.
  225. if test -n "$tracemmap"; then
  226. add_env="$add_env MEMUSAGE_TRACE_MMAP=yes"
  227. fi
  228. # Execute the program itself.
  229. eval $add_env '"$@"'
  230. result=$?
  231. # Generate the PNG data file if wanted and there is something to generate
  232. # it from.
  233. if test -n "$png" -a -n "$datafile" -a -s "$datafile"; then
  234. # Append extension .png if it isn't already there.
  235. case $png in
  236. *.png) ;;
  237. *) png="$png.png" ;;
  238. esac
  239. $memusagestat $memusagestat_args "$datafile" "$png"
  240. fi
  241. if test -z "$data" -a -n "$datafile"; then
  242. rm -f "$datafile"
  243. fi
  244. exit $result
  245. # Local Variables:
  246. # mode:ksh
  247. # End: