M r2-amsdump.cabal => r2-amsdump.cabal +1 -1
@@ 23,6 23,6 @@ executable r2-amsdump
-- other-extensions:
build-depends: base >=4.12 && <5,
r2pipe, bytestring, aeson, binary, utf8-string,
- optparse-applicative, regex-tdfa, transformers, table-layout
+ optparse-applicative, regex-pcre-builtin, transformers, table-layout
hs-source-dirs: src
default-language: Haskell2010
M src/Stacktrace.hs => src/Stacktrace.hs +12 -7
@@ 6,11 6,12 @@ module Stacktrace (stacktrace) where
import GHC.Generics
import qualified Data.Aeson as JSON
import Data.Word
-import Text.Regex.TDFA
+import Text.Regex.PCRE
import Text.Printf
import Data.Maybe
import Data.Char (isSpace)
import Text.Layout.Table
+import Data.List (sortOn)
import qualified Data.ByteString.Lazy.UTF8 as BU
import R2Pipe
@@ 27,17 28,21 @@ data Flag = Flag
stacktrace :: Maybe Int -> R2Context -> IO ()
stacktrace th r = do
let regex = case th of
- Just tid -> printf "th%d(.crash)?" tid
+ Just tid -> printf "th%d(?:.crash)?" tid
Nothing -> printf "th[0-9]+\\.crash"
- ++ "\\.stacktrace\\.[0-9]+"
+ ++ "\\.stacktrace\\.([0-9]+)"
flags <- fromJust <$> ((cmdj r "fj@F:dump")::(IO (Maybe [Flag])))
- let traceflags = filter (\f -> (name f) =~ regex) flags
- if null traceflags then
+ let traceflags = mapMaybe (\f -> let match = (name f =~ regex) :: [[String]] in
+ case match of
+ [[_, num]] -> Just (f, (read num) :: Int)
+ _ -> Nothing) flags
+ let sorted = reverse $ sortOn (\(_, num) -> num) traceflags
+ if null sorted then
putStrLn "No Stacktrace flags found for this thread."
else do
- flagcols <- mapM (\flag -> do
+ flagcols <- mapM (\(flag, num) -> do
desc <- BU.toString <$> cmd r (printf "fd @ %#x @F:symbols" $ offset flag)
- return $ trim <$> [printf "%#010x" $ offset flag, name flag, desc]) traceflags
+ return $ trim <$> [printf "%#010x" $ offset flag, name flag, desc]) sorted
let table = tableString [def, def, def] unicodeS (titlesH ["Address", "Flag", "Description"]) $ rowG <$> flagcols
putStrLn table