int page_num;
 };
 
-static int sort_by_memory;
 static regex_t order_pattern;
 static struct block_list *list;
 static int list_size;
 
 static void usage(void)
 {
-       printf("Usage: ./page_owner_sort [-m] <input> <output>\n"
-               "-m     Sort by total memory. If this option is unset, sort by times\n"
+       printf("Usage: ./page_owner_sort [OPTIONS] <input> <output>\n"
+               "-m     Sort by total memory.\n"
+               "-s     Sort by the stack trace.\n"
+               "-t     Sort by times (default).\n"
        );
 }
 
 int main(int argc, char **argv)
 {
+       int (*cmp)(const void *, const void *) = compare_num;
        FILE *fin, *fout;
        char *buf;
        int ret, i, count;
        int err;
        int opt;
 
-       while ((opt = getopt(argc, argv, "m")) != -1)
+       while ((opt = getopt(argc, argv, "mst")) != -1)
                switch (opt) {
                case 'm':
-                       sort_by_memory = 1;
+                       cmp = compare_page_num;
+                       break;
+               case 's':
+                       cmp = compare_stacktrace;
+                       break;
+               case 't':
+                       cmp = compare_num;
                        break;
                default:
                        usage();
                }
        }
 
-       if (sort_by_memory)
-               qsort(list2, count, sizeof(list[0]), compare_page_num);
-       else
-               qsort(list2, count, sizeof(list[0]), compare_num);
+       qsort(list2, count, sizeof(list[0]), cmp);
 
        for (i = 0; i < count; i++)
                fprintf(fout, "%d times, %d pages:\n%s\n",