You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

backward.hpp 138KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471
  1. /*
  2. * backward.hpp
  3. * Copyright 2013 Google Inc. All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21. * SOFTWARE.
  22. */
  23. #ifndef H_6B9572DA_A64B_49E6_B234_051480991C89
  24. #define H_6B9572DA_A64B_49E6_B234_051480991C89
  25. #ifndef __cplusplus
  26. #error "It's not going to compile without a C++ compiler..."
  27. #endif
  28. #if defined(BACKWARD_CXX11)
  29. #elif defined(BACKWARD_CXX98)
  30. #else
  31. #if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
  32. #define BACKWARD_CXX11
  33. #define BACKWARD_ATLEAST_CXX11
  34. #define BACKWARD_ATLEAST_CXX98
  35. #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
  36. #define BACKWARD_ATLEAST_CXX17
  37. #endif
  38. #else
  39. #define BACKWARD_CXX98
  40. #define BACKWARD_ATLEAST_CXX98
  41. #endif
  42. #endif
  43. // You can define one of the following (or leave it to the auto-detection):
  44. //
  45. // #define BACKWARD_SYSTEM_LINUX
  46. // - specialization for linux
  47. //
  48. // #define BACKWARD_SYSTEM_DARWIN
  49. // - specialization for Mac OS X 10.5 and later.
  50. //
  51. // #define BACKWARD_SYSTEM_WINDOWS
  52. // - specialization for Windows (Clang 9 and MSVC2017)
  53. //
  54. // #define BACKWARD_SYSTEM_UNKNOWN
  55. // - placebo implementation, does nothing.
  56. //
  57. #if defined(BACKWARD_SYSTEM_LINUX)
  58. #elif defined(BACKWARD_SYSTEM_DARWIN)
  59. #elif defined(BACKWARD_SYSTEM_UNKNOWN)
  60. #elif defined(BACKWARD_SYSTEM_WINDOWS)
  61. #else
  62. #if defined(__linux) || defined(__linux__)
  63. #define BACKWARD_SYSTEM_LINUX
  64. #elif defined(__APPLE__)
  65. #define BACKWARD_SYSTEM_DARWIN
  66. #elif defined(_WIN32)
  67. #define BACKWARD_SYSTEM_WINDOWS
  68. #else
  69. #define BACKWARD_SYSTEM_UNKNOWN
  70. #endif
  71. #endif
  72. #define NOINLINE __attribute__((noinline))
  73. #include <algorithm>
  74. #include <cctype>
  75. #include <cstdio>
  76. #include <cstdlib>
  77. #include <cstring>
  78. #include <fstream>
  79. #include <iomanip>
  80. #include <iostream>
  81. #include <limits>
  82. #include <new>
  83. #include <sstream>
  84. #include <streambuf>
  85. #include <string>
  86. #include <vector>
  87. #include <exception>
  88. #include <iterator>
  89. #if defined(BACKWARD_SYSTEM_LINUX)
  90. // On linux, backtrace can back-trace or "walk" the stack using the following
  91. // libraries:
  92. //
  93. // #define BACKWARD_HAS_UNWIND 1
  94. // - unwind comes from libgcc, but I saw an equivalent inside clang itself.
  95. // - with unwind, the stacktrace is as accurate as it can possibly be, since
  96. // this is used by the C++ runtine in gcc/clang for stack unwinding on
  97. // exception.
  98. // - normally libgcc is already linked to your program by default.
  99. //
  100. // #define BACKWARD_HAS_LIBUNWIND 1
  101. // - libunwind provides, in some cases, a more accurate stacktrace as it knows
  102. // to decode signal handler frames and lets us edit the context registers when
  103. // unwinding, allowing stack traces over bad function references.
  104. //
  105. // #define BACKWARD_HAS_BACKTRACE == 1
  106. // - backtrace seems to be a little bit more portable than libunwind, but on
  107. // linux, it uses unwind anyway, but abstract away a tiny information that is
  108. // sadly really important in order to get perfectly accurate stack traces.
  109. // - backtrace is part of the (e)glib library.
  110. //
  111. // The default is:
  112. // #define BACKWARD_HAS_UNWIND == 1
  113. //
  114. // Note that only one of the define should be set to 1 at a time.
  115. //
  116. #if BACKWARD_HAS_UNWIND == 1
  117. #elif BACKWARD_HAS_LIBUNWIND == 1
  118. #elif BACKWARD_HAS_BACKTRACE == 1
  119. #else
  120. #undef BACKWARD_HAS_UNWIND
  121. #define BACKWARD_HAS_UNWIND 1
  122. #undef BACKWARD_HAS_LIBUNWIND
  123. #define BACKWARD_HAS_LIBUNWIND 0
  124. #undef BACKWARD_HAS_BACKTRACE
  125. #define BACKWARD_HAS_BACKTRACE 0
  126. #endif
  127. // On linux, backward can extract detailed information about a stack trace
  128. // using one of the following libraries:
  129. //
  130. // #define BACKWARD_HAS_DW 1
  131. // - libdw gives you the most juicy details out of your stack traces:
  132. // - object filename
  133. // - function name
  134. // - source filename
  135. // - line and column numbers
  136. // - source code snippet (assuming the file is accessible)
  137. // - variable names (if not optimized out)
  138. // - variable values (not supported by backward-cpp)
  139. // - You need to link with the lib "dw":
  140. // - apt-get install libdw-dev
  141. // - g++/clang++ -ldw ...
  142. //
  143. // #define BACKWARD_HAS_BFD 1
  144. // - With libbfd, you get a fair amount of details:
  145. // - object filename
  146. // - function name
  147. // - source filename
  148. // - line numbers
  149. // - source code snippet (assuming the file is accessible)
  150. // - You need to link with the lib "bfd":
  151. // - apt-get install binutils-dev
  152. // - g++/clang++ -lbfd ...
  153. //
  154. // #define BACKWARD_HAS_DWARF 1
  155. // - libdwarf gives you the most juicy details out of your stack traces:
  156. // - object filename
  157. // - function name
  158. // - source filename
  159. // - line and column numbers
  160. // - source code snippet (assuming the file is accessible)
  161. // - variable names (if not optimized out)
  162. // - variable values (not supported by backward-cpp)
  163. // - You need to link with the lib "dwarf":
  164. // - apt-get install libdwarf-dev
  165. // - g++/clang++ -ldwarf ...
  166. //
  167. // #define BACKWARD_HAS_BACKTRACE_SYMBOL 1
  168. // - backtrace provides minimal details for a stack trace:
  169. // - object filename
  170. // - function name
  171. // - backtrace is part of the (e)glib library.
  172. //
  173. // The default is:
  174. // #define BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  175. //
  176. // Note that only one of the define should be set to 1 at a time.
  177. //
  178. #if BACKWARD_HAS_DW == 1
  179. #elif BACKWARD_HAS_BFD == 1
  180. #elif BACKWARD_HAS_DWARF == 1
  181. #elif BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  182. #else
  183. #undef BACKWARD_HAS_DW
  184. #define BACKWARD_HAS_DW 0
  185. #undef BACKWARD_HAS_BFD
  186. #define BACKWARD_HAS_BFD 0
  187. #undef BACKWARD_HAS_DWARF
  188. #define BACKWARD_HAS_DWARF 0
  189. #undef BACKWARD_HAS_BACKTRACE_SYMBOL
  190. #define BACKWARD_HAS_BACKTRACE_SYMBOL 1
  191. #endif
  192. #include <cxxabi.h>
  193. #include <fcntl.h>
  194. #ifdef __ANDROID__
  195. // Old Android API levels define _Unwind_Ptr in both link.h and
  196. // unwind.h Rename the one in link.h as we are not going to be using
  197. // it
  198. #define _Unwind_Ptr _Unwind_Ptr_Custom
  199. #include <link.h>
  200. #undef _Unwind_Ptr
  201. #else
  202. #include <link.h>
  203. #endif
  204. #if defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
  205. defined(__POWERPC__)
  206. // Linux kernel header required for the struct pt_regs definition
  207. // to access the NIP (Next Instruction Pointer) register value
  208. #include <asm/ptrace.h>
  209. #endif
  210. #include <signal.h>
  211. #include <sys/stat.h>
  212. #include <syscall.h>
  213. #include <unistd.h>
  214. #ifndef _GNU_SOURCE
  215. #define _GNU_SOURCE
  216. #include <dlfcn.h>
  217. #undef _GNU_SOURCE
  218. #else
  219. #include <dlfcn.h>
  220. #endif
  221. #if BACKWARD_HAS_BFD == 1
  222. // NOTE: defining PACKAGE{,_VERSION} is required before including
  223. // bfd.h on some platforms, see also:
  224. // https://sourceware.org/bugzilla/show_bug.cgi?id=14243
  225. #ifndef PACKAGE
  226. #define PACKAGE
  227. #endif
  228. #ifndef PACKAGE_VERSION
  229. #define PACKAGE_VERSION
  230. #endif
  231. #include <bfd.h>
  232. #endif
  233. #if BACKWARD_HAS_DW == 1
  234. #include <dwarf.h>
  235. #include <elfutils/libdw.h>
  236. #include <elfutils/libdwfl.h>
  237. #endif
  238. #if BACKWARD_HAS_DWARF == 1
  239. #include <algorithm>
  240. #include <dwarf.h>
  241. #include <libdwarf.h>
  242. #include <libelf.h>
  243. #include <map>
  244. #endif
  245. #if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1)
  246. // then we shall rely on backtrace
  247. #include <execinfo.h>
  248. #endif
  249. #endif // defined(BACKWARD_SYSTEM_LINUX)
  250. #if defined(BACKWARD_SYSTEM_DARWIN)
  251. // On Darwin, backtrace can back-trace or "walk" the stack using the following
  252. // libraries:
  253. //
  254. // #define BACKWARD_HAS_UNWIND 1
  255. // - unwind comes from libgcc, but I saw an equivalent inside clang itself.
  256. // - with unwind, the stacktrace is as accurate as it can possibly be, since
  257. // this is used by the C++ runtine in gcc/clang for stack unwinding on
  258. // exception.
  259. // - normally libgcc is already linked to your program by default.
  260. //
  261. // #define BACKWARD_HAS_LIBUNWIND 1
  262. // - libunwind comes from clang, which implements an API compatible version.
  263. // - libunwind provides, in some cases, a more accurate stacktrace as it knows
  264. // to decode signal handler frames and lets us edit the context registers when
  265. // unwinding, allowing stack traces over bad function references.
  266. //
  267. // #define BACKWARD_HAS_BACKTRACE == 1
  268. // - backtrace is available by default, though it does not produce as much
  269. // information as another library might.
  270. //
  271. // The default is:
  272. // #define BACKWARD_HAS_UNWIND == 1
  273. //
  274. // Note that only one of the define should be set to 1 at a time.
  275. //
  276. #if BACKWARD_HAS_UNWIND == 1
  277. #elif BACKWARD_HAS_BACKTRACE == 1
  278. #elif BACKWARD_HAS_LIBUNWIND == 1
  279. #else
  280. #undef BACKWARD_HAS_UNWIND
  281. #define BACKWARD_HAS_UNWIND 1
  282. #undef BACKWARD_HAS_BACKTRACE
  283. #define BACKWARD_HAS_BACKTRACE 0
  284. #undef BACKWARD_HAS_LIBUNWIND
  285. #define BACKWARD_HAS_LIBUNWIND 0
  286. #endif
  287. // On Darwin, backward can extract detailed information about a stack trace
  288. // using one of the following libraries:
  289. //
  290. // #define BACKWARD_HAS_BACKTRACE_SYMBOL 1
  291. // - backtrace provides minimal details for a stack trace:
  292. // - object filename
  293. // - function name
  294. //
  295. // The default is:
  296. // #define BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  297. //
  298. #if BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  299. #else
  300. #undef BACKWARD_HAS_BACKTRACE_SYMBOL
  301. #define BACKWARD_HAS_BACKTRACE_SYMBOL 1
  302. #endif
  303. #include <cxxabi.h>
  304. #include <fcntl.h>
  305. #include <pthread.h>
  306. #include <signal.h>
  307. #include <sys/stat.h>
  308. #include <unistd.h>
  309. #if (BACKWARD_HAS_BACKTRACE == 1) || (BACKWARD_HAS_BACKTRACE_SYMBOL == 1)
  310. #include <execinfo.h>
  311. #endif
  312. #endif // defined(BACKWARD_SYSTEM_DARWIN)
  313. #if defined(BACKWARD_SYSTEM_WINDOWS)
  314. #include <condition_variable>
  315. #include <mutex>
  316. #include <thread>
  317. #include <basetsd.h>
  318. typedef SSIZE_T ssize_t;
  319. #ifndef NOMINMAX
  320. #define NOMINMAX
  321. #endif
  322. #include <windows.h>
  323. #include <winnt.h>
  324. #include <psapi.h>
  325. #include <signal.h>
  326. #ifndef __clang__
  327. #undef NOINLINE
  328. #define NOINLINE __declspec(noinline)
  329. #endif
  330. #ifdef _MSC_VER
  331. #pragma comment(lib, "psapi.lib")
  332. #pragma comment(lib, "dbghelp.lib")
  333. #endif
  334. // Comment / packing is from stackoverflow:
  335. // https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app/28276227#28276227
  336. // Some versions of imagehlp.dll lack the proper packing directives themselves
  337. // so we need to do it.
  338. #pragma pack(push, before_imagehlp, 8)
  339. #include <imagehlp.h>
  340. #pragma pack(pop, before_imagehlp)
  341. // TODO maybe these should be undefined somewhere else?
  342. #undef BACKWARD_HAS_UNWIND
  343. #undef BACKWARD_HAS_BACKTRACE
  344. #if BACKWARD_HAS_PDB_SYMBOL == 1
  345. #else
  346. #undef BACKWARD_HAS_PDB_SYMBOL
  347. #define BACKWARD_HAS_PDB_SYMBOL 1
  348. #endif
  349. #endif
  350. #if BACKWARD_HAS_UNWIND == 1
  351. #ifndef _GNU_SOURCE
  352. #define _GNU_SOURCE
  353. #include <unwind.h>
  354. #undef _GNU_SOURCE
  355. #else
  356. #include <unwind.h>
  357. #endif
  358. // while gcc's unwind.h defines something like that:
  359. // extern _Unwind_Ptr _Unwind_GetIP (struct _Unwind_Context *);
  360. // extern _Unwind_Ptr _Unwind_GetIPInfo (struct _Unwind_Context *, int *);
  361. //
  362. // clang's unwind.h defines something like this:
  363. // uintptr_t _Unwind_GetIP(struct _Unwind_Context* __context);
  364. //
  365. // Even if the _Unwind_GetIPInfo can be linked to, it is not declared, worse we
  366. // cannot just redeclare it because clang's unwind.h doesn't define _Unwind_Ptr
  367. // anyway.
  368. //
  369. // Luckily we can play on the fact that the guard macros have a different name:
  370. #ifdef __CLANG_UNWIND_H
  371. // In fact, this function still comes from libgcc (on my different linux boxes,
  372. // clang links against libgcc).
  373. #include <inttypes.h>
  374. extern "C" uintptr_t _Unwind_GetIPInfo(_Unwind_Context *, int *);
  375. #endif
  376. #endif // BACKWARD_HAS_UNWIND == 1
  377. #if BACKWARD_HAS_LIBUNWIND == 1
  378. #define UNW_LOCAL_ONLY
  379. #include <libunwind.h>
  380. #endif // BACKWARD_HAS_LIBUNWIND == 1
  381. #ifdef BACKWARD_ATLEAST_CXX11
  382. #include <unordered_map>
  383. #include <utility> // for std::swap
  384. namespace backward {
  385. namespace details {
  386. template <typename K, typename V> struct hashtable {
  387. typedef std::unordered_map<K, V> type;
  388. };
  389. using std::move;
  390. } // namespace details
  391. } // namespace backward
  392. #else // NOT BACKWARD_ATLEAST_CXX11
  393. #define nullptr NULL
  394. #define override
  395. #include <map>
  396. namespace backward {
  397. namespace details {
  398. template <typename K, typename V> struct hashtable {
  399. typedef std::map<K, V> type;
  400. };
  401. template <typename T> const T &move(const T &v) { return v; }
  402. template <typename T> T &move(T &v) { return v; }
  403. } // namespace details
  404. } // namespace backward
  405. #endif // BACKWARD_ATLEAST_CXX11
  406. namespace backward {
  407. namespace details {
  408. #if defined(BACKWARD_SYSTEM_WINDOWS)
  409. const char kBackwardPathDelimiter[] = ";";
  410. #else
  411. const char kBackwardPathDelimiter[] = ":";
  412. #endif
  413. } // namespace details
  414. } // namespace backward
  415. namespace backward {
  416. namespace system_tag {
  417. struct linux_tag; // seems that I cannot call that "linux" because the name
  418. // is already defined... so I am adding _tag everywhere.
  419. struct darwin_tag;
  420. struct windows_tag;
  421. struct unknown_tag;
  422. #if defined(BACKWARD_SYSTEM_LINUX)
  423. typedef linux_tag current_tag;
  424. #elif defined(BACKWARD_SYSTEM_DARWIN)
  425. typedef darwin_tag current_tag;
  426. #elif defined(BACKWARD_SYSTEM_WINDOWS)
  427. typedef windows_tag current_tag;
  428. #elif defined(BACKWARD_SYSTEM_UNKNOWN)
  429. typedef unknown_tag current_tag;
  430. #else
  431. #error "May I please get my system defines?"
  432. #endif
  433. } // namespace system_tag
  434. namespace trace_resolver_tag {
  435. #if defined(BACKWARD_SYSTEM_LINUX)
  436. struct libdw;
  437. struct libbfd;
  438. struct libdwarf;
  439. struct backtrace_symbol;
  440. #if BACKWARD_HAS_DW == 1
  441. typedef libdw current;
  442. #elif BACKWARD_HAS_BFD == 1
  443. typedef libbfd current;
  444. #elif BACKWARD_HAS_DWARF == 1
  445. typedef libdwarf current;
  446. #elif BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  447. typedef backtrace_symbol current;
  448. #else
  449. #error "You shall not pass, until you know what you want."
  450. #endif
  451. #elif defined(BACKWARD_SYSTEM_DARWIN)
  452. struct backtrace_symbol;
  453. #if BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  454. typedef backtrace_symbol current;
  455. #else
  456. #error "You shall not pass, until you know what you want."
  457. #endif
  458. #elif defined(BACKWARD_SYSTEM_WINDOWS)
  459. struct pdb_symbol;
  460. #if BACKWARD_HAS_PDB_SYMBOL == 1
  461. typedef pdb_symbol current;
  462. #else
  463. #error "You shall not pass, until you know what you want."
  464. #endif
  465. #endif
  466. } // namespace trace_resolver_tag
  467. namespace details {
  468. template <typename T> struct rm_ptr { typedef T type; };
  469. template <typename T> struct rm_ptr<T *> { typedef T type; };
  470. template <typename T> struct rm_ptr<const T *> { typedef const T type; };
  471. template <typename R, typename T, R (*F)(T)> struct deleter {
  472. template <typename U> void operator()(U &ptr) const { (*F)(ptr); }
  473. };
  474. template <typename T> struct default_delete {
  475. void operator()(T &ptr) const { delete ptr; }
  476. };
  477. template <typename T, typename Deleter = deleter<void, void *, &::free>>
  478. class handle {
  479. struct dummy;
  480. T _val;
  481. bool _empty;
  482. #ifdef BACKWARD_ATLEAST_CXX11
  483. handle(const handle &) = delete;
  484. handle &operator=(const handle &) = delete;
  485. #endif
  486. public:
  487. ~handle() {
  488. if (!_empty) {
  489. Deleter()(_val);
  490. }
  491. }
  492. explicit handle() : _val(), _empty(true) {}
  493. explicit handle(T val) : _val(val), _empty(false) {
  494. if (!_val)
  495. _empty = true;
  496. }
  497. #ifdef BACKWARD_ATLEAST_CXX11
  498. handle(handle &&from) : _empty(true) { swap(from); }
  499. handle &operator=(handle &&from) {
  500. swap(from);
  501. return *this;
  502. }
  503. #else
  504. explicit handle(const handle &from) : _empty(true) {
  505. // some sort of poor man's move semantic.
  506. swap(const_cast<handle &>(from));
  507. }
  508. handle &operator=(const handle &from) {
  509. // some sort of poor man's move semantic.
  510. swap(const_cast<handle &>(from));
  511. return *this;
  512. }
  513. #endif
  514. void reset(T new_val) {
  515. handle tmp(new_val);
  516. swap(tmp);
  517. }
  518. void update(T new_val) {
  519. _val = new_val;
  520. _empty = !static_cast<bool>(new_val);
  521. }
  522. operator const dummy *() const {
  523. if (_empty) {
  524. return nullptr;
  525. }
  526. return reinterpret_cast<const dummy *>(_val);
  527. }
  528. T get() { return _val; }
  529. T release() {
  530. _empty = true;
  531. return _val;
  532. }
  533. void swap(handle &b) {
  534. using std::swap;
  535. swap(b._val, _val); // can throw, we are safe here.
  536. swap(b._empty, _empty); // should not throw: if you cannot swap two
  537. // bools without throwing... It's a lost cause anyway!
  538. }
  539. T &operator->() { return _val; }
  540. const T &operator->() const { return _val; }
  541. typedef typename rm_ptr<T>::type &ref_t;
  542. typedef const typename rm_ptr<T>::type &const_ref_t;
  543. ref_t operator*() { return *_val; }
  544. const_ref_t operator*() const { return *_val; }
  545. ref_t operator[](size_t idx) { return _val[idx]; }
  546. // Watch out, we've got a badass over here
  547. T *operator&() {
  548. _empty = false;
  549. return &_val;
  550. }
  551. };
  552. // Default demangler implementation (do nothing).
  553. template <typename TAG> struct demangler_impl {
  554. static std::string demangle(const char *funcname) { return funcname; }
  555. };
  556. #if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN)
  557. template <> struct demangler_impl<system_tag::current_tag> {
  558. demangler_impl() : _demangle_buffer_length(0) {}
  559. std::string demangle(const char *funcname) {
  560. using namespace details;
  561. char *result = abi::__cxa_demangle(funcname, _demangle_buffer.get(),
  562. &_demangle_buffer_length, nullptr);
  563. if (result) {
  564. _demangle_buffer.update(result);
  565. return result;
  566. }
  567. return funcname;
  568. }
  569. private:
  570. details::handle<char *> _demangle_buffer;
  571. size_t _demangle_buffer_length;
  572. };
  573. #endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN
  574. struct demangler : public demangler_impl<system_tag::current_tag> {};
  575. // Split a string on the platform's PATH delimiter. Example: if delimiter
  576. // is ":" then:
  577. // "" --> []
  578. // ":" --> ["",""]
  579. // "::" --> ["","",""]
  580. // "/a/b/c" --> ["/a/b/c"]
  581. // "/a/b/c:/d/e/f" --> ["/a/b/c","/d/e/f"]
  582. // etc.
  583. inline std::vector<std::string> split_source_prefixes(const std::string &s) {
  584. std::vector<std::string> out;
  585. size_t last = 0;
  586. size_t next = 0;
  587. size_t delimiter_size = sizeof(kBackwardPathDelimiter) - 1;
  588. while ((next = s.find(kBackwardPathDelimiter, last)) != std::string::npos) {
  589. out.push_back(s.substr(last, next - last));
  590. last = next + delimiter_size;
  591. }
  592. if (last <= s.length()) {
  593. out.push_back(s.substr(last));
  594. }
  595. return out;
  596. }
  597. } // namespace details
  598. /*************** A TRACE ***************/
  599. struct Trace {
  600. void *addr;
  601. size_t idx;
  602. Trace() : addr(nullptr), idx(0) {}
  603. explicit Trace(void *_addr, size_t _idx) : addr(_addr), idx(_idx) {}
  604. };
  605. struct ResolvedTrace : public Trace {
  606. struct SourceLoc {
  607. std::string function;
  608. std::string filename;
  609. unsigned line;
  610. unsigned col;
  611. SourceLoc() : line(0), col(0) {}
  612. bool operator==(const SourceLoc &b) const {
  613. return function == b.function && filename == b.filename &&
  614. line == b.line && col == b.col;
  615. }
  616. bool operator!=(const SourceLoc &b) const { return !(*this == b); }
  617. };
  618. // In which binary object this trace is located.
  619. std::string object_filename;
  620. // The function in the object that contain the trace. This is not the same
  621. // as source.function which can be an function inlined in object_function.
  622. std::string object_function;
  623. // The source location of this trace. It is possible for filename to be
  624. // empty and for line/col to be invalid (value 0) if this information
  625. // couldn't be deduced, for example if there is no debug information in the
  626. // binary object.
  627. SourceLoc source;
  628. // An optionals list of "inliners". All the successive sources location
  629. // from where the source location of the trace (the attribute right above)
  630. // is inlined. It is especially useful when you compiled with optimization.
  631. typedef std::vector<SourceLoc> source_locs_t;
  632. source_locs_t inliners;
  633. ResolvedTrace() : Trace() {}
  634. ResolvedTrace(const Trace &mini_trace) : Trace(mini_trace) {}
  635. };
  636. /*************** STACK TRACE ***************/
  637. // default implemention.
  638. template <typename TAG> class StackTraceImpl {
  639. public:
  640. size_t size() const { return 0; }
  641. Trace operator[](size_t) const { return Trace(); }
  642. size_t load_here(size_t = 0) { return 0; }
  643. size_t load_from(void *, size_t = 0, void * = nullptr, void * = nullptr) {
  644. return 0;
  645. }
  646. size_t thread_id() const { return 0; }
  647. void skip_n_firsts(size_t) {}
  648. };
  649. class StackTraceImplBase {
  650. public:
  651. StackTraceImplBase()
  652. : _thread_id(0), _skip(0), _context(nullptr), _error_addr(nullptr) {}
  653. size_t thread_id() const { return _thread_id; }
  654. void skip_n_firsts(size_t n) { _skip = n; }
  655. protected:
  656. void load_thread_info() {
  657. #ifdef BACKWARD_SYSTEM_LINUX
  658. #ifndef __ANDROID__
  659. _thread_id = static_cast<size_t>(syscall(SYS_gettid));
  660. #else
  661. _thread_id = static_cast<size_t>(gettid());
  662. #endif
  663. if (_thread_id == static_cast<size_t>(getpid())) {
  664. // If the thread is the main one, let's hide that.
  665. // I like to keep little secret sometimes.
  666. _thread_id = 0;
  667. }
  668. #elif defined(BACKWARD_SYSTEM_DARWIN)
  669. _thread_id = reinterpret_cast<size_t>(pthread_self());
  670. if (pthread_main_np() == 1) {
  671. // If the thread is the main one, let's hide that.
  672. _thread_id = 0;
  673. }
  674. #endif
  675. }
  676. void set_context(void *context) { _context = context; }
  677. void *context() const { return _context; }
  678. void set_error_addr(void *error_addr) { _error_addr = error_addr; }
  679. void *error_addr() const { return _error_addr; }
  680. size_t skip_n_firsts() const { return _skip; }
  681. private:
  682. size_t _thread_id;
  683. size_t _skip;
  684. void *_context;
  685. void *_error_addr;
  686. };
  687. class StackTraceImplHolder : public StackTraceImplBase {
  688. public:
  689. size_t size() const {
  690. return (_stacktrace.size() >= skip_n_firsts())
  691. ? _stacktrace.size() - skip_n_firsts()
  692. : 0;
  693. }
  694. Trace operator[](size_t idx) const {
  695. if (idx >= size()) {
  696. return Trace();
  697. }
  698. return Trace(_stacktrace[idx + skip_n_firsts()], idx);
  699. }
  700. void *const *begin() const {
  701. if (size()) {
  702. return &_stacktrace[skip_n_firsts()];
  703. }
  704. return nullptr;
  705. }
  706. protected:
  707. std::vector<void *> _stacktrace;
  708. };
  709. #if BACKWARD_HAS_UNWIND == 1
  710. namespace details {
  711. template <typename F> class Unwinder {
  712. public:
  713. size_t operator()(F &f, size_t depth) {
  714. _f = &f;
  715. _index = -1;
  716. _depth = depth;
  717. _Unwind_Backtrace(&this->backtrace_trampoline, this);
  718. return static_cast<size_t>(_index);
  719. }
  720. private:
  721. F *_f;
  722. ssize_t _index;
  723. size_t _depth;
  724. static _Unwind_Reason_Code backtrace_trampoline(_Unwind_Context *ctx,
  725. void *self) {
  726. return (static_cast<Unwinder *>(self))->backtrace(ctx);
  727. }
  728. _Unwind_Reason_Code backtrace(_Unwind_Context *ctx) {
  729. if (_index >= 0 && static_cast<size_t>(_index) >= _depth)
  730. return _URC_END_OF_STACK;
  731. int ip_before_instruction = 0;
  732. uintptr_t ip = _Unwind_GetIPInfo(ctx, &ip_before_instruction);
  733. if (!ip_before_instruction) {
  734. // calculating 0-1 for unsigned, looks like a possible bug to sanitiziers,
  735. // so let's do it explicitly:
  736. if (ip == 0) {
  737. ip = std::numeric_limits<uintptr_t>::max(); // set it to 0xffff... (as
  738. // from casting 0-1)
  739. } else {
  740. ip -= 1; // else just normally decrement it (no overflow/underflow will
  741. // happen)
  742. }
  743. }
  744. if (_index >= 0) { // ignore first frame.
  745. (*_f)(static_cast<size_t>(_index), reinterpret_cast<void *>(ip));
  746. }
  747. _index += 1;
  748. return _URC_NO_REASON;
  749. }
  750. };
  751. template <typename F> size_t unwind(F f, size_t depth) {
  752. Unwinder<F> unwinder;
  753. return unwinder(f, depth);
  754. }
  755. } // namespace details
  756. template <>
  757. class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
  758. public:
  759. NOINLINE
  760. size_t load_here(size_t depth = 32, void *context = nullptr,
  761. void *error_addr = nullptr) {
  762. load_thread_info();
  763. set_context(context);
  764. set_error_addr(error_addr);
  765. if (depth == 0) {
  766. return 0;
  767. }
  768. _stacktrace.resize(depth);
  769. size_t trace_cnt = details::unwind(callback(*this), depth);
  770. _stacktrace.resize(trace_cnt);
  771. skip_n_firsts(0);
  772. return size();
  773. }
  774. size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
  775. void *error_addr = nullptr) {
  776. load_here(depth + 8, context, error_addr);
  777. for (size_t i = 0; i < _stacktrace.size(); ++i) {
  778. if (_stacktrace[i] == addr) {
  779. skip_n_firsts(i);
  780. break;
  781. }
  782. }
  783. _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth));
  784. return size();
  785. }
  786. private:
  787. struct callback {
  788. StackTraceImpl &self;
  789. callback(StackTraceImpl &_self) : self(_self) {}
  790. void operator()(size_t idx, void *addr) { self._stacktrace[idx] = addr; }
  791. };
  792. };
  793. #elif BACKWARD_HAS_LIBUNWIND == 1
  794. template <>
  795. class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
  796. public:
  797. __attribute__((noinline)) size_t load_here(size_t depth = 32,
  798. void *_context = nullptr,
  799. void *_error_addr = nullptr) {
  800. set_context(_context);
  801. set_error_addr(_error_addr);
  802. load_thread_info();
  803. if (depth == 0) {
  804. return 0;
  805. }
  806. _stacktrace.resize(depth + 1);
  807. int result = 0;
  808. unw_context_t ctx;
  809. size_t index = 0;
  810. // Add the tail call. If the Instruction Pointer is the crash address it
  811. // means we got a bad function pointer dereference, so we "unwind" the
  812. // bad pointer manually by using the return address pointed to by the
  813. // Stack Pointer as the Instruction Pointer and letting libunwind do
  814. // the rest
  815. if (context()) {
  816. ucontext_t *uctx = reinterpret_cast<ucontext_t *>(context());
  817. #ifdef REG_RIP // x86_64
  818. if (uctx->uc_mcontext.gregs[REG_RIP] ==
  819. reinterpret_cast<greg_t>(error_addr())) {
  820. uctx->uc_mcontext.gregs[REG_RIP] =
  821. *reinterpret_cast<size_t *>(uctx->uc_mcontext.gregs[REG_RSP]);
  822. }
  823. _stacktrace[index] =
  824. reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_RIP]);
  825. ++index;
  826. ctx = *reinterpret_cast<unw_context_t *>(uctx);
  827. #elif defined(REG_EIP) // x86_32
  828. if (uctx->uc_mcontext.gregs[REG_EIP] ==
  829. reinterpret_cast<greg_t>(error_addr())) {
  830. uctx->uc_mcontext.gregs[REG_EIP] =
  831. *reinterpret_cast<size_t *>(uctx->uc_mcontext.gregs[REG_ESP]);
  832. }
  833. _stacktrace[index] =
  834. reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_EIP]);
  835. ++index;
  836. ctx = *reinterpret_cast<unw_context_t *>(uctx);
  837. #elif defined(__arm__)
  838. // libunwind uses its own context type for ARM unwinding.
  839. // Copy the registers from the signal handler's context so we can
  840. // unwind
  841. unw_getcontext(&ctx);
  842. ctx.regs[UNW_ARM_R0] = uctx->uc_mcontext.arm_r0;
  843. ctx.regs[UNW_ARM_R1] = uctx->uc_mcontext.arm_r1;
  844. ctx.regs[UNW_ARM_R2] = uctx->uc_mcontext.arm_r2;
  845. ctx.regs[UNW_ARM_R3] = uctx->uc_mcontext.arm_r3;
  846. ctx.regs[UNW_ARM_R4] = uctx->uc_mcontext.arm_r4;
  847. ctx.regs[UNW_ARM_R5] = uctx->uc_mcontext.arm_r5;
  848. ctx.regs[UNW_ARM_R6] = uctx->uc_mcontext.arm_r6;
  849. ctx.regs[UNW_ARM_R7] = uctx->uc_mcontext.arm_r7;
  850. ctx.regs[UNW_ARM_R8] = uctx->uc_mcontext.arm_r8;
  851. ctx.regs[UNW_ARM_R9] = uctx->uc_mcontext.arm_r9;
  852. ctx.regs[UNW_ARM_R10] = uctx->uc_mcontext.arm_r10;
  853. ctx.regs[UNW_ARM_R11] = uctx->uc_mcontext.arm_fp;
  854. ctx.regs[UNW_ARM_R12] = uctx->uc_mcontext.arm_ip;
  855. ctx.regs[UNW_ARM_R13] = uctx->uc_mcontext.arm_sp;
  856. ctx.regs[UNW_ARM_R14] = uctx->uc_mcontext.arm_lr;
  857. ctx.regs[UNW_ARM_R15] = uctx->uc_mcontext.arm_pc;
  858. // If we have crashed in the PC use the LR instead, as this was
  859. // a bad function dereference
  860. if (reinterpret_cast<unsigned long>(error_addr()) ==
  861. uctx->uc_mcontext.arm_pc) {
  862. ctx.regs[UNW_ARM_R15] =
  863. uctx->uc_mcontext.arm_lr - sizeof(unsigned long);
  864. }
  865. _stacktrace[index] = reinterpret_cast<void *>(ctx.regs[UNW_ARM_R15]);
  866. ++index;
  867. #elif defined(__APPLE__) && defined(__x86_64__)
  868. unw_getcontext(&ctx);
  869. // OS X's implementation of libunwind uses its own context object
  870. // so we need to convert the passed context to libunwind's format
  871. // (information about the data layout taken from unw_getcontext.s
  872. // in Apple's libunwind source
  873. ctx.data[0] = uctx->uc_mcontext->__ss.__rax;
  874. ctx.data[1] = uctx->uc_mcontext->__ss.__rbx;
  875. ctx.data[2] = uctx->uc_mcontext->__ss.__rcx;
  876. ctx.data[3] = uctx->uc_mcontext->__ss.__rdx;
  877. ctx.data[4] = uctx->uc_mcontext->__ss.__rdi;
  878. ctx.data[5] = uctx->uc_mcontext->__ss.__rsi;
  879. ctx.data[6] = uctx->uc_mcontext->__ss.__rbp;
  880. ctx.data[7] = uctx->uc_mcontext->__ss.__rsp;
  881. ctx.data[8] = uctx->uc_mcontext->__ss.__r8;
  882. ctx.data[9] = uctx->uc_mcontext->__ss.__r9;
  883. ctx.data[10] = uctx->uc_mcontext->__ss.__r10;
  884. ctx.data[11] = uctx->uc_mcontext->__ss.__r11;
  885. ctx.data[12] = uctx->uc_mcontext->__ss.__r12;
  886. ctx.data[13] = uctx->uc_mcontext->__ss.__r13;
  887. ctx.data[14] = uctx->uc_mcontext->__ss.__r14;
  888. ctx.data[15] = uctx->uc_mcontext->__ss.__r15;
  889. ctx.data[16] = uctx->uc_mcontext->__ss.__rip;
  890. // If the IP is the same as the crash address we have a bad function
  891. // dereference The caller's address is pointed to by %rsp, so we
  892. // dereference that value and set it to be the next frame's IP.
  893. if (uctx->uc_mcontext->__ss.__rip ==
  894. reinterpret_cast<__uint64_t>(error_addr())) {
  895. ctx.data[16] =
  896. *reinterpret_cast<__uint64_t *>(uctx->uc_mcontext->__ss.__rsp);
  897. }
  898. _stacktrace[index] = reinterpret_cast<void *>(ctx.data[16]);
  899. ++index;
  900. #elif defined(__APPLE__)
  901. unw_getcontext(&ctx)
  902. // TODO: Convert the ucontext_t to libunwind's unw_context_t like
  903. // we do in 64 bits
  904. if (ctx.uc_mcontext->__ss.__eip ==
  905. reinterpret_cast<greg_t>(error_addr())) {
  906. ctx.uc_mcontext->__ss.__eip = ctx.uc_mcontext->__ss.__esp;
  907. }
  908. _stacktrace[index] =
  909. reinterpret_cast<void *>(ctx.uc_mcontext->__ss.__eip);
  910. ++index;
  911. #endif
  912. }
  913. unw_cursor_t cursor;
  914. if (context()) {
  915. #if defined(UNW_INIT_SIGNAL_FRAME)
  916. result = unw_init_local2(&cursor, &ctx, UNW_INIT_SIGNAL_FRAME);
  917. #else
  918. result = unw_init_local(&cursor, &ctx);
  919. #endif
  920. } else {
  921. unw_getcontext(&ctx);
  922. ;
  923. result = unw_init_local(&cursor, &ctx);
  924. }
  925. if (result != 0)
  926. return 1;
  927. unw_word_t ip = 0;
  928. while (index <= depth && unw_step(&cursor) > 0) {
  929. result = unw_get_reg(&cursor, UNW_REG_IP, &ip);
  930. if (result == 0) {
  931. _stacktrace[index] = reinterpret_cast<void *>(--ip);
  932. ++index;
  933. }
  934. }
  935. --index;
  936. _stacktrace.resize(index + 1);
  937. skip_n_firsts(0);
  938. return size();
  939. }
  940. size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
  941. void *error_addr = nullptr) {
  942. load_here(depth + 8, context, error_addr);
  943. for (size_t i = 0; i < _stacktrace.size(); ++i) {
  944. if (_stacktrace[i] == addr) {
  945. skip_n_firsts(i);
  946. _stacktrace[i] = (void *)((uintptr_t)_stacktrace[i]);
  947. break;
  948. }
  949. }
  950. _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth));
  951. return size();
  952. }
  953. };
  954. #elif defined(BACKWARD_HAS_BACKTRACE)
  955. template <>
  956. class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
  957. public:
  958. NOINLINE
  959. size_t load_here(size_t depth = 32, void *context = nullptr,
  960. void *error_addr = nullptr) {
  961. set_context(context);
  962. set_error_addr(error_addr);
  963. load_thread_info();
  964. if (depth == 0) {
  965. return 0;
  966. }
  967. _stacktrace.resize(depth + 1);
  968. size_t trace_cnt = backtrace(&_stacktrace[0], _stacktrace.size());
  969. _stacktrace.resize(trace_cnt);
  970. skip_n_firsts(1);
  971. return size();
  972. }
  973. size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
  974. void *error_addr = nullptr) {
  975. load_here(depth + 8, context, error_addr);
  976. for (size_t i = 0; i < _stacktrace.size(); ++i) {
  977. if (_stacktrace[i] == addr) {
  978. skip_n_firsts(i);
  979. _stacktrace[i] = (void *)((uintptr_t)_stacktrace[i] + 1);
  980. break;
  981. }
  982. }
  983. _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth));
  984. return size();
  985. }
  986. };
  987. #elif defined(BACKWARD_SYSTEM_WINDOWS)
  988. template <>
  989. class StackTraceImpl<system_tag::current_tag> : public StackTraceImplHolder {
  990. public:
  991. // We have to load the machine type from the image info
  992. // So we first initialize the resolver, and it tells us this info
  993. void set_machine_type(DWORD machine_type) { machine_type_ = machine_type; }
  994. void set_context(CONTEXT *ctx) { ctx_ = ctx; }
  995. void set_thread_handle(HANDLE handle) { thd_ = handle; }
  996. NOINLINE
  997. size_t load_here(size_t depth = 32, void *context = nullptr,
  998. void *error_addr = nullptr) {
  999. set_context(static_cast<CONTEXT*>(context));
  1000. set_error_addr(error_addr);
  1001. CONTEXT localCtx; // used when no context is provided
  1002. if (depth == 0) {
  1003. return 0;
  1004. }
  1005. if (!ctx_) {
  1006. ctx_ = &localCtx;
  1007. RtlCaptureContext(ctx_);
  1008. }
  1009. if (!thd_) {
  1010. thd_ = GetCurrentThread();
  1011. }
  1012. HANDLE process = GetCurrentProcess();
  1013. STACKFRAME64 s;
  1014. memset(&s, 0, sizeof(STACKFRAME64));
  1015. // TODO: 32 bit context capture
  1016. s.AddrStack.Mode = AddrModeFlat;
  1017. s.AddrFrame.Mode = AddrModeFlat;
  1018. s.AddrPC.Mode = AddrModeFlat;
  1019. #ifdef _M_X64
  1020. s.AddrPC.Offset = ctx_->Rip;
  1021. s.AddrStack.Offset = ctx_->Rsp;
  1022. s.AddrFrame.Offset = ctx_->Rbp;
  1023. #else
  1024. s.AddrPC.Offset = ctx_->Eip;
  1025. s.AddrStack.Offset = ctx_->Esp;
  1026. s.AddrFrame.Offset = ctx_->Ebp;
  1027. #endif
  1028. if (!machine_type_) {
  1029. #ifdef _M_X64
  1030. machine_type_ = IMAGE_FILE_MACHINE_AMD64;
  1031. #else
  1032. machine_type_ = IMAGE_FILE_MACHINE_I386;
  1033. #endif
  1034. }
  1035. for (;;) {
  1036. // NOTE: this only works if PDBs are already loaded!
  1037. SetLastError(0);
  1038. if (!StackWalk64(machine_type_, process, thd_, &s, ctx_, NULL,
  1039. SymFunctionTableAccess64, SymGetModuleBase64, NULL))
  1040. break;
  1041. if (s.AddrReturn.Offset == 0)
  1042. break;
  1043. _stacktrace.push_back(reinterpret_cast<void *>(s.AddrPC.Offset));
  1044. if (size() >= depth)
  1045. break;
  1046. }
  1047. return size();
  1048. }
  1049. size_t load_from(void *addr, size_t depth = 32, void *context = nullptr,
  1050. void *error_addr = nullptr) {
  1051. load_here(depth + 8, context, error_addr);
  1052. for (size_t i = 0; i < _stacktrace.size(); ++i) {
  1053. if (_stacktrace[i] == addr) {
  1054. skip_n_firsts(i);
  1055. break;
  1056. }
  1057. }
  1058. _stacktrace.resize(std::min(_stacktrace.size(), skip_n_firsts() + depth));
  1059. return size();
  1060. }
  1061. private:
  1062. DWORD machine_type_ = 0;
  1063. HANDLE thd_ = 0;
  1064. CONTEXT *ctx_ = nullptr;
  1065. };
  1066. #endif
  1067. class StackTrace : public StackTraceImpl<system_tag::current_tag> {};
  1068. /*************** TRACE RESOLVER ***************/
  1069. class TraceResolverImplBase {
  1070. public:
  1071. virtual ~TraceResolverImplBase() {}
  1072. virtual void load_addresses(void *const*addresses, int address_count) {
  1073. (void)addresses;
  1074. (void)address_count;
  1075. }
  1076. template <class ST> void load_stacktrace(ST &st) {
  1077. load_addresses(st.begin(), (int)st.size());
  1078. }
  1079. virtual ResolvedTrace resolve(ResolvedTrace t) { return t; }
  1080. protected:
  1081. std::string demangle(const char *funcname) {
  1082. return _demangler.demangle(funcname);
  1083. }
  1084. private:
  1085. details::demangler _demangler;
  1086. };
  1087. template <typename TAG> class TraceResolverImpl;
  1088. #ifdef BACKWARD_SYSTEM_UNKNOWN
  1089. template <> class TraceResolverImpl<system_tag::unknown_tag>
  1090. : public TraceResolverImplBase {};
  1091. #endif
  1092. #ifdef BACKWARD_SYSTEM_LINUX
  1093. class TraceResolverLinuxBase : public TraceResolverImplBase {
  1094. public:
  1095. TraceResolverLinuxBase()
  1096. : argv0_(get_argv0()), exec_path_(read_symlink("/proc/self/exe")) {}
  1097. std::string resolve_exec_path(Dl_info &symbol_info) const {
  1098. // mutates symbol_info.dli_fname to be filename to open and returns filename
  1099. // to display
  1100. if (symbol_info.dli_fname == argv0_) {
  1101. // dladdr returns argv[0] in dli_fname for symbols contained in
  1102. // the main executable, which is not a valid path if the
  1103. // executable was found by a search of the PATH environment
  1104. // variable; In that case, we actually open /proc/self/exe, which
  1105. // is always the actual executable (even if it was deleted/replaced!)
  1106. // but display the path that /proc/self/exe links to.
  1107. // However, this right away reduces probability of successful symbol
  1108. // resolution, because libbfd may try to find *.debug files in the
  1109. // same dir, in case symbols are stripped. As a result, it may try
  1110. // to find a file /proc/self/<exe_name>.debug, which obviously does
  1111. // not exist. /proc/self/exe is a last resort. First load attempt
  1112. // should go for the original executable file path.
  1113. symbol_info.dli_fname = "/proc/self/exe";
  1114. return exec_path_;
  1115. } else {
  1116. return symbol_info.dli_fname;
  1117. }
  1118. }
  1119. private:
  1120. std::string argv0_;
  1121. std::string exec_path_;
  1122. static std::string get_argv0() {
  1123. std::string argv0;
  1124. std::ifstream ifs("/proc/self/cmdline");
  1125. std::getline(ifs, argv0, '\0');
  1126. return argv0;
  1127. }
  1128. static std::string read_symlink(std::string const &symlink_path) {
  1129. std::string path;
  1130. path.resize(100);
  1131. while (true) {
  1132. ssize_t len =
  1133. ::readlink(symlink_path.c_str(), &*path.begin(), path.size());
  1134. if (len < 0) {
  1135. return "";
  1136. }
  1137. if (static_cast<size_t>(len) == path.size()) {
  1138. path.resize(path.size() * 2);
  1139. } else {
  1140. path.resize(static_cast<std::string::size_type>(len));
  1141. break;
  1142. }
  1143. }
  1144. return path;
  1145. }
  1146. };
  1147. template <typename STACKTRACE_TAG> class TraceResolverLinuxImpl;
  1148. #if BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  1149. template <>
  1150. class TraceResolverLinuxImpl<trace_resolver_tag::backtrace_symbol>
  1151. : public TraceResolverLinuxBase {
  1152. public:
  1153. void load_addresses(void *const*addresses, int address_count) override {
  1154. if (address_count == 0) {
  1155. return;
  1156. }
  1157. _symbols.reset(backtrace_symbols(addresses, address_count));
  1158. }
  1159. ResolvedTrace resolve(ResolvedTrace trace) override {
  1160. char *filename = _symbols[trace.idx];
  1161. char *funcname = filename;
  1162. while (*funcname && *funcname != '(') {
  1163. funcname += 1;
  1164. }
  1165. trace.object_filename.assign(filename,
  1166. funcname); // ok even if funcname is the ending
  1167. // \0 (then we assign entire string)
  1168. if (*funcname) { // if it's not end of string (e.g. from last frame ip==0)
  1169. funcname += 1;
  1170. char *funcname_end = funcname;
  1171. while (*funcname_end && *funcname_end != ')' && *funcname_end != '+') {
  1172. funcname_end += 1;
  1173. }
  1174. *funcname_end = '\0';
  1175. trace.object_function = this->demangle(funcname);
  1176. trace.source.function = trace.object_function; // we cannot do better.
  1177. }
  1178. return trace;
  1179. }
  1180. private:
  1181. details::handle<char **> _symbols;
  1182. };
  1183. #endif // BACKWARD_HAS_BACKTRACE_SYMBOL == 1
  1184. #if BACKWARD_HAS_BFD == 1
  1185. template <>
  1186. class TraceResolverLinuxImpl<trace_resolver_tag::libbfd>
  1187. : public TraceResolverLinuxBase {
  1188. public:
  1189. TraceResolverLinuxImpl() : _bfd_loaded(false) {}
  1190. ResolvedTrace resolve(ResolvedTrace trace) override {
  1191. Dl_info symbol_info;
  1192. // trace.addr is a virtual address in memory pointing to some code.
  1193. // Let's try to find from which loaded object it comes from.
  1194. // The loaded object can be yourself btw.
  1195. if (!dladdr(trace.addr, &symbol_info)) {
  1196. return trace; // dat broken trace...
  1197. }
  1198. // Now we get in symbol_info:
  1199. // .dli_fname:
  1200. // pathname of the shared object that contains the address.
  1201. // .dli_fbase:
  1202. // where the object is loaded in memory.
  1203. // .dli_sname:
  1204. // the name of the nearest symbol to trace.addr, we expect a
  1205. // function name.
  1206. // .dli_saddr:
  1207. // the exact address corresponding to .dli_sname.
  1208. if (symbol_info.dli_sname) {
  1209. trace.object_function = demangle(symbol_info.dli_sname);
  1210. }
  1211. if (!symbol_info.dli_fname) {
  1212. return trace;
  1213. }
  1214. trace.object_filename = resolve_exec_path(symbol_info);
  1215. bfd_fileobject *fobj;
  1216. // Before rushing to resolution need to ensure the executable
  1217. // file still can be used. For that compare inode numbers of
  1218. // what is stored by the executable's file path, and in the
  1219. // dli_fname, which not necessarily equals to the executable.
  1220. // It can be a shared library, or /proc/self/exe, and in the
  1221. // latter case has drawbacks. See the exec path resolution for
  1222. // details. In short - the dli object should be used only as
  1223. // the last resort.
  1224. // If inode numbers are equal, it is known dli_fname and the
  1225. // executable file are the same. This is guaranteed by Linux,
  1226. // because if the executable file is changed/deleted, it will
  1227. // be done in a new inode. The old file will be preserved in
  1228. // /proc/self/exe, and may even have inode 0. The latter can
  1229. // happen if the inode was actually reused, and the file was
  1230. // kept only in the main memory.
  1231. //
  1232. struct stat obj_stat;
  1233. struct stat dli_stat;
  1234. if (stat(trace.object_filename.c_str(), &obj_stat) == 0 &&
  1235. stat(symbol_info.dli_fname, &dli_stat) == 0 &&
  1236. obj_stat.st_ino == dli_stat.st_ino) {
  1237. // The executable file, and the shared object containing the
  1238. // address are the same file. Safe to use the original path.
  1239. // this is preferable. Libbfd will search for stripped debug
  1240. // symbols in the same directory.
  1241. fobj = load_object_with_bfd(trace.object_filename);
  1242. } else{
  1243. // The original object file was *deleted*! The only hope is
  1244. // that the debug symbols are either inside the shared
  1245. // object file, or are in the same directory, and this is
  1246. // not /proc/self/exe.
  1247. fobj = nullptr;
  1248. }
  1249. if (fobj == nullptr || !fobj->handle) {
  1250. fobj = load_object_with_bfd(symbol_info.dli_fname);
  1251. if (!fobj->handle) {
  1252. return trace;
  1253. }
  1254. }
  1255. find_sym_result *details_selected; // to be filled.
  1256. // trace.addr is the next instruction to be executed after returning
  1257. // from the nested stack frame. In C++ this usually relate to the next
  1258. // statement right after the function call that leaded to a new stack
  1259. // frame. This is not usually what you want to see when printing out a
  1260. // stacktrace...
  1261. find_sym_result details_call_site =
  1262. find_symbol_details(fobj, trace.addr, symbol_info.dli_fbase);
  1263. details_selected = &details_call_site;
  1264. #if BACKWARD_HAS_UNWIND == 0
  1265. // ...this is why we also try to resolve the symbol that is right
  1266. // before the return address. If we are lucky enough, we will get the
  1267. // line of the function that was called. But if the code is optimized,
  1268. // we might get something absolutely not related since the compiler
  1269. // can reschedule the return address with inline functions and
  1270. // tail-call optimisation (among other things that I don't even know
  1271. // or cannot even dream about with my tiny limited brain).
  1272. find_sym_result details_adjusted_call_site = find_symbol_details(
  1273. fobj, (void *)(uintptr_t(trace.addr) - 1), symbol_info.dli_fbase);
  1274. // In debug mode, we should always get the right thing(TM).
  1275. if (details_call_site.found && details_adjusted_call_site.found) {
  1276. // Ok, we assume that details_adjusted_call_site is a better estimation.
  1277. details_selected = &details_adjusted_call_site;
  1278. trace.addr = (void *)(uintptr_t(trace.addr) - 1);
  1279. }
  1280. if (details_selected == &details_call_site && details_call_site.found) {
  1281. // we have to re-resolve the symbol in order to reset some
  1282. // internal state in BFD... so we can call backtrace_inliners
  1283. // thereafter...
  1284. details_call_site =
  1285. find_symbol_details(fobj, trace.addr, symbol_info.dli_fbase);
  1286. }
  1287. #endif // BACKWARD_HAS_UNWIND
  1288. if (details_selected->found) {
  1289. if (details_selected->filename) {
  1290. trace.source.filename = details_selected->filename;
  1291. }
  1292. trace.source.line = details_selected->line;
  1293. if (details_selected->funcname) {
  1294. // this time we get the name of the function where the code is
  1295. // located, instead of the function were the address is
  1296. // located. In short, if the code was inlined, we get the
  1297. // function correspoding to the code. Else we already got in
  1298. // trace.function.
  1299. trace.source.function = demangle(details_selected->funcname);
  1300. if (!symbol_info.dli_sname) {
  1301. // for the case dladdr failed to find the symbol name of
  1302. // the function, we might as well try to put something
  1303. // here.
  1304. trace.object_function = trace.source.function;
  1305. }
  1306. }
  1307. // Maybe the source of the trace got inlined inside the function
  1308. // (trace.source.function). Let's see if we can get all the inlined
  1309. // calls along the way up to the initial call site.
  1310. trace.inliners = backtrace_inliners(fobj, *details_selected);
  1311. #if 0
  1312. if (trace.inliners.size() == 0) {
  1313. // Maybe the trace was not inlined... or maybe it was and we
  1314. // are lacking the debug information. Let's try to make the
  1315. // world better and see if we can get the line number of the
  1316. // function (trace.source.function) now.
  1317. //
  1318. // We will get the location of where the function start (to be
  1319. // exact: the first instruction that really start the
  1320. // function), not where the name of the function is defined.
  1321. // This can be quite far away from the name of the function
  1322. // btw.
  1323. //
  1324. // If the source of the function is the same as the source of
  1325. // the trace, we cannot say if the trace was really inlined or
  1326. // not. However, if the filename of the source is different
  1327. // between the function and the trace... we can declare it as
  1328. // an inliner. This is not 100% accurate, but better than
  1329. // nothing.
  1330. if (symbol_info.dli_saddr) {
  1331. find_sym_result details = find_symbol_details(fobj,
  1332. symbol_info.dli_saddr,
  1333. symbol_info.dli_fbase);
  1334. if (details.found) {
  1335. ResolvedTrace::SourceLoc diy_inliner;
  1336. diy_inliner.line = details.line;
  1337. if (details.filename) {
  1338. diy_inliner.filename = details.filename;
  1339. }
  1340. if (details.funcname) {
  1341. diy_inliner.function = demangle(details.funcname);
  1342. } else {
  1343. diy_inliner.function = trace.source.function;
  1344. }
  1345. if (diy_inliner != trace.source) {
  1346. trace.inliners.push_back(diy_inliner);
  1347. }
  1348. }
  1349. }
  1350. }
  1351. #endif
  1352. }
  1353. return trace;
  1354. }
  1355. private:
  1356. bool _bfd_loaded;
  1357. typedef details::handle<bfd *,
  1358. details::deleter<bfd_boolean, bfd *, &bfd_close>>
  1359. bfd_handle_t;
  1360. typedef details::handle<asymbol **> bfd_symtab_t;
  1361. struct bfd_fileobject {
  1362. bfd_handle_t handle;
  1363. bfd_vma base_addr;
  1364. bfd_symtab_t symtab;
  1365. bfd_symtab_t dynamic_symtab;
  1366. };
  1367. typedef details::hashtable<std::string, bfd_fileobject>::type fobj_bfd_map_t;
  1368. fobj_bfd_map_t _fobj_bfd_map;
  1369. bfd_fileobject *load_object_with_bfd(const std::string &filename_object) {
  1370. using namespace details;
  1371. if (!_bfd_loaded) {
  1372. using namespace details;
  1373. bfd_init();
  1374. _bfd_loaded = true;
  1375. }
  1376. fobj_bfd_map_t::iterator it = _fobj_bfd_map.find(filename_object);
  1377. if (it != _fobj_bfd_map.end()) {
  1378. return &it->second;
  1379. }
  1380. // this new object is empty for now.
  1381. bfd_fileobject *r = &_fobj_bfd_map[filename_object];
  1382. // we do the work temporary in this one;
  1383. bfd_handle_t bfd_handle;
  1384. int fd = open(filename_object.c_str(), O_RDONLY);
  1385. bfd_handle.reset(bfd_fdopenr(filename_object.c_str(), "default", fd));
  1386. if (!bfd_handle) {
  1387. close(fd);
  1388. return r;
  1389. }
  1390. if (!bfd_check_format(bfd_handle.get(), bfd_object)) {
  1391. return r; // not an object? You lose.
  1392. }
  1393. if ((bfd_get_file_flags(bfd_handle.get()) & HAS_SYMS) == 0) {
  1394. return r; // that's what happen when you forget to compile in debug.
  1395. }
  1396. ssize_t symtab_storage_size = bfd_get_symtab_upper_bound(bfd_handle.get());
  1397. ssize_t dyn_symtab_storage_size =
  1398. bfd_get_dynamic_symtab_upper_bound(bfd_handle.get());
  1399. if (symtab_storage_size <= 0 && dyn_symtab_storage_size <= 0) {
  1400. return r; // weird, is the file is corrupted?
  1401. }
  1402. bfd_symtab_t symtab, dynamic_symtab;
  1403. ssize_t symcount = 0, dyn_symcount = 0;
  1404. if (symtab_storage_size > 0) {
  1405. symtab.reset(static_cast<bfd_symbol **>(
  1406. malloc(static_cast<size_t>(symtab_storage_size))));
  1407. symcount = bfd_canonicalize_symtab(bfd_handle.get(), symtab.get());
  1408. }
  1409. if (dyn_symtab_storage_size > 0) {
  1410. dynamic_symtab.reset(static_cast<bfd_symbol **>(
  1411. malloc(static_cast<size_t>(dyn_symtab_storage_size))));
  1412. dyn_symcount = bfd_canonicalize_dynamic_symtab(bfd_handle.get(),
  1413. dynamic_symtab.get());
  1414. }
  1415. if (symcount <= 0 && dyn_symcount <= 0) {
  1416. return r; // damned, that's a stripped file that you got there!
  1417. }
  1418. r->handle = move(bfd_handle);
  1419. r->symtab = move(symtab);
  1420. r->dynamic_symtab = move(dynamic_symtab);
  1421. return r;
  1422. }
  1423. struct find_sym_result {
  1424. bool found;
  1425. const char *filename;
  1426. const char *funcname;
  1427. unsigned int line;
  1428. };
  1429. struct find_sym_context {
  1430. TraceResolverLinuxImpl *self;
  1431. bfd_fileobject *fobj;
  1432. void *addr;
  1433. void *base_addr;
  1434. find_sym_result result;
  1435. };
  1436. find_sym_result find_symbol_details(bfd_fileobject *fobj, void *addr,
  1437. void *base_addr) {
  1438. find_sym_context context;
  1439. context.self = this;
  1440. context.fobj = fobj;
  1441. context.addr = addr;
  1442. context.base_addr = base_addr;
  1443. context.result.found = false;
  1444. bfd_map_over_sections(fobj->handle.get(), &find_in_section_trampoline,
  1445. static_cast<void *>(&context));
  1446. return context.result;
  1447. }
  1448. static void find_in_section_trampoline(bfd *, asection *section, void *data) {
  1449. find_sym_context *context = static_cast<find_sym_context *>(data);
  1450. context->self->find_in_section(
  1451. reinterpret_cast<bfd_vma>(context->addr),
  1452. reinterpret_cast<bfd_vma>(context->base_addr), context->fobj, section,
  1453. context->result);
  1454. }
  1455. void find_in_section(bfd_vma addr, bfd_vma base_addr, bfd_fileobject *fobj,
  1456. asection *section, find_sym_result &result) {
  1457. if (result.found)
  1458. return;
  1459. #ifdef bfd_get_section_flags
  1460. if ((bfd_get_section_flags(fobj->handle.get(), section) & SEC_ALLOC) == 0)
  1461. #else
  1462. if ((bfd_section_flags(section) & SEC_ALLOC) == 0)
  1463. #endif
  1464. return; // a debug section is never loaded automatically.
  1465. #ifdef bfd_get_section_vma
  1466. bfd_vma sec_addr = bfd_get_section_vma(fobj->handle.get(), section);
  1467. #else
  1468. bfd_vma sec_addr = bfd_section_vma(section);
  1469. #endif
  1470. #ifdef bfd_get_section_size
  1471. bfd_size_type size = bfd_get_section_size(section);
  1472. #else
  1473. bfd_size_type size = bfd_section_size(section);
  1474. #endif
  1475. // are we in the boundaries of the section?
  1476. if (addr < sec_addr || addr >= sec_addr + size) {
  1477. addr -= base_addr; // oups, a relocated object, lets try again...
  1478. if (addr < sec_addr || addr >= sec_addr + size) {
  1479. return;
  1480. }
  1481. }
  1482. #if defined(__clang__)
  1483. #pragma clang diagnostic push
  1484. #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
  1485. #endif
  1486. if (!result.found && fobj->symtab) {
  1487. result.found = bfd_find_nearest_line(
  1488. fobj->handle.get(), section, fobj->symtab.get(), addr - sec_addr,
  1489. &result.filename, &result.funcname, &result.line);
  1490. }
  1491. if (!result.found && fobj->dynamic_symtab) {
  1492. result.found = bfd_find_nearest_line(
  1493. fobj->handle.get(), section, fobj->dynamic_symtab.get(),
  1494. addr - sec_addr, &result.filename, &result.funcname, &result.line);
  1495. }
  1496. #if defined(__clang__)
  1497. #pragma clang diagnostic pop
  1498. #endif
  1499. }
  1500. ResolvedTrace::source_locs_t
  1501. backtrace_inliners(bfd_fileobject *fobj, find_sym_result previous_result) {
  1502. // This function can be called ONLY after a SUCCESSFUL call to
  1503. // find_symbol_details. The state is global to the bfd_handle.
  1504. ResolvedTrace::source_locs_t results;
  1505. while (previous_result.found) {
  1506. find_sym_result result;
  1507. result.found = bfd_find_inliner_info(fobj->handle.get(), &result.filename,
  1508. &result.funcname, &result.line);
  1509. if (result
  1510. .found) /* and not (
  1511. cstrings_eq(previous_result.filename,
  1512. result.filename) and
  1513. cstrings_eq(previous_result.funcname, result.funcname)
  1514. and result.line == previous_result.line
  1515. )) */
  1516. {
  1517. ResolvedTrace::SourceLoc src_loc;
  1518. src_loc.line = result.line;
  1519. if (result.filename) {
  1520. src_loc.filename = result.filename;
  1521. }
  1522. if (result.funcname) {
  1523. src_loc.function = demangle(result.funcname);
  1524. }
  1525. results.push_back(src_loc);
  1526. }
  1527. previous_result = result;
  1528. }
  1529. return results;
  1530. }
  1531. bool cstrings_eq(const char *a, const char *b) {
  1532. if (!a || !b) {
  1533. return false;
  1534. }
  1535. return strcmp(a, b) == 0;
  1536. }
  1537. };
  1538. #endif // BACKWARD_HAS_BFD == 1
  1539. #if BACKWARD_HAS_DW == 1
  1540. template <>
  1541. class TraceResolverLinuxImpl<trace_resolver_tag::libdw>
  1542. : public TraceResolverLinuxBase {
  1543. public:
  1544. TraceResolverLinuxImpl() : _dwfl_handle_initialized(false) {}
  1545. ResolvedTrace resolve(ResolvedTrace trace) override {
  1546. using namespace details;
  1547. Dwarf_Addr trace_addr = (Dwarf_Addr)trace.addr;
  1548. if (!_dwfl_handle_initialized) {
  1549. // initialize dwfl...
  1550. _dwfl_cb.reset(new Dwfl_Callbacks);
  1551. _dwfl_cb->find_elf = &dwfl_linux_proc_find_elf;
  1552. _dwfl_cb->find_debuginfo = &dwfl_standard_find_debuginfo;
  1553. _dwfl_cb->debuginfo_path = 0;
  1554. _dwfl_handle.reset(dwfl_begin(_dwfl_cb.get()));
  1555. _dwfl_handle_initialized = true;
  1556. if (!_dwfl_handle) {
  1557. return trace;
  1558. }
  1559. // ...from the current process.
  1560. dwfl_report_begin(_dwfl_handle.get());
  1561. int r = dwfl_linux_proc_report(_dwfl_handle.get(), getpid());
  1562. dwfl_report_end(_dwfl_handle.get(), NULL, NULL);
  1563. if (r < 0) {
  1564. return trace;
  1565. }
  1566. }
  1567. if (!_dwfl_handle) {
  1568. return trace;
  1569. }
  1570. // find the module (binary object) that contains the trace's address.
  1571. // This is not using any debug information, but the addresses ranges of
  1572. // all the currently loaded binary object.
  1573. Dwfl_Module *mod = dwfl_addrmodule(_dwfl_handle.get(), trace_addr);
  1574. if (mod) {
  1575. // now that we found it, lets get the name of it, this will be the
  1576. // full path to the running binary or one of the loaded library.
  1577. const char *module_name = dwfl_module_info(mod, 0, 0, 0, 0, 0, 0, 0);
  1578. if (module_name) {
  1579. trace.object_filename = module_name;
  1580. }
  1581. // We also look after the name of the symbol, equal or before this
  1582. // address. This is found by walking the symtab. We should get the
  1583. // symbol corresponding to the function (mangled) containing the
  1584. // address. If the code corresponding to the address was inlined,
  1585. // this is the name of the out-most inliner function.
  1586. const char *sym_name = dwfl_module_addrname(mod, trace_addr);
  1587. if (sym_name) {
  1588. trace.object_function = demangle(sym_name);
  1589. }
  1590. }
  1591. // now let's get serious, and find out the source location (file and
  1592. // line number) of the address.
  1593. // This function will look in .debug_aranges for the address and map it
  1594. // to the location of the compilation unit DIE in .debug_info and
  1595. // return it.
  1596. Dwarf_Addr mod_bias = 0;
  1597. Dwarf_Die *cudie = dwfl_module_addrdie(mod, trace_addr, &mod_bias);
  1598. #if 1
  1599. if (!cudie) {
  1600. // Sadly clang does not generate the section .debug_aranges, thus
  1601. // dwfl_module_addrdie will fail early. Clang doesn't either set
  1602. // the lowpc/highpc/range info for every compilation unit.
  1603. //
  1604. // So in order to save the world:
  1605. // for every compilation unit, we will iterate over every single
  1606. // DIEs. Normally functions should have a lowpc/highpc/range, which
  1607. // we will use to infer the compilation unit.
  1608. // note that this is probably badly inefficient.
  1609. while ((cudie = dwfl_module_nextcu(mod, cudie, &mod_bias))) {
  1610. Dwarf_Die die_mem;
  1611. Dwarf_Die *fundie =
  1612. find_fundie_by_pc(cudie, trace_addr - mod_bias, &die_mem);
  1613. if (fundie) {
  1614. break;
  1615. }
  1616. }
  1617. }
  1618. #endif
  1619. //#define BACKWARD_I_DO_NOT_RECOMMEND_TO_ENABLE_THIS_HORRIBLE_PIECE_OF_CODE
  1620. #ifdef BACKWARD_I_DO_NOT_RECOMMEND_TO_ENABLE_THIS_HORRIBLE_PIECE_OF_CODE
  1621. if (!cudie) {
  1622. // If it's still not enough, lets dive deeper in the shit, and try
  1623. // to save the world again: for every compilation unit, we will
  1624. // load the corresponding .debug_line section, and see if we can
  1625. // find our address in it.
  1626. Dwarf_Addr cfi_bias;
  1627. Dwarf_CFI *cfi_cache = dwfl_module_eh_cfi(mod, &cfi_bias);
  1628. Dwarf_Addr bias;
  1629. while ((cudie = dwfl_module_nextcu(mod, cudie, &bias))) {
  1630. if (dwarf_getsrc_die(cudie, trace_addr - bias)) {
  1631. // ...but if we get a match, it might be a false positive
  1632. // because our (address - bias) might as well be valid in a
  1633. // different compilation unit. So we throw our last card on
  1634. // the table and lookup for the address into the .eh_frame
  1635. // section.
  1636. handle<Dwarf_Frame *> frame;
  1637. dwarf_cfi_addrframe(cfi_cache, trace_addr - cfi_bias, &frame);
  1638. if (frame) {
  1639. break;
  1640. }
  1641. }
  1642. }
  1643. }
  1644. #endif
  1645. if (!cudie) {
  1646. return trace; // this time we lost the game :/
  1647. }
  1648. // Now that we have a compilation unit DIE, this function will be able
  1649. // to load the corresponding section in .debug_line (if not already
  1650. // loaded) and hopefully find the source location mapped to our
  1651. // address.
  1652. Dwarf_Line *srcloc = dwarf_getsrc_die(cudie, trace_addr - mod_bias);
  1653. if (srcloc) {
  1654. const char *srcfile = dwarf_linesrc(srcloc, 0, 0);
  1655. if (srcfile) {
  1656. trace.source.filename = srcfile;
  1657. }
  1658. int line = 0, col = 0;
  1659. dwarf_lineno(srcloc, &line);
  1660. dwarf_linecol(srcloc, &col);
  1661. trace.source.line = line;
  1662. trace.source.col = col;
  1663. }
  1664. deep_first_search_by_pc(cudie, trace_addr - mod_bias,
  1665. inliners_search_cb(trace));
  1666. if (trace.source.function.size() == 0) {
  1667. // fallback.
  1668. trace.source.function = trace.object_function;
  1669. }
  1670. return trace;
  1671. }
  1672. private:
  1673. typedef details::handle<Dwfl *, details::deleter<void, Dwfl *, &dwfl_end>>
  1674. dwfl_handle_t;
  1675. details::handle<Dwfl_Callbacks *, details::default_delete<Dwfl_Callbacks *>>
  1676. _dwfl_cb;
  1677. dwfl_handle_t _dwfl_handle;
  1678. bool _dwfl_handle_initialized;
  1679. // defined here because in C++98, template function cannot take locally
  1680. // defined types... grrr.
  1681. struct inliners_search_cb {
  1682. void operator()(Dwarf_Die *die) {
  1683. switch (dwarf_tag(die)) {
  1684. const char *name;
  1685. case DW_TAG_subprogram:
  1686. if ((name = dwarf_diename(die))) {
  1687. trace.source.function = name;
  1688. }
  1689. break;
  1690. case DW_TAG_inlined_subroutine:
  1691. ResolvedTrace::SourceLoc sloc;
  1692. Dwarf_Attribute attr_mem;
  1693. if ((name = dwarf_diename(die))) {
  1694. sloc.function = name;
  1695. }
  1696. if ((name = die_call_file(die))) {
  1697. sloc.filename = name;
  1698. }
  1699. Dwarf_Word line = 0, col = 0;
  1700. dwarf_formudata(dwarf_attr(die, DW_AT_call_line, &attr_mem), &line);
  1701. dwarf_formudata(dwarf_attr(die, DW_AT_call_column, &attr_mem), &col);
  1702. sloc.line = (unsigned)line;
  1703. sloc.col = (unsigned)col;
  1704. trace.inliners.push_back(sloc);
  1705. break;
  1706. };
  1707. }
  1708. ResolvedTrace &trace;
  1709. inliners_search_cb(ResolvedTrace &t) : trace(t) {}
  1710. };
  1711. static bool die_has_pc(Dwarf_Die *die, Dwarf_Addr pc) {
  1712. Dwarf_Addr low, high;
  1713. // continuous range
  1714. if (dwarf_hasattr(die, DW_AT_low_pc) && dwarf_hasattr(die, DW_AT_high_pc)) {
  1715. if (dwarf_lowpc(die, &low) != 0) {
  1716. return false;
  1717. }
  1718. if (dwarf_highpc(die, &high) != 0) {
  1719. Dwarf_Attribute attr_mem;
  1720. Dwarf_Attribute *attr = dwarf_attr(die, DW_AT_high_pc, &attr_mem);
  1721. Dwarf_Word value;
  1722. if (dwarf_formudata(attr, &value) != 0) {
  1723. return false;
  1724. }
  1725. high = low + value;
  1726. }
  1727. return pc >= low && pc < high;
  1728. }
  1729. // non-continuous range.
  1730. Dwarf_Addr base;
  1731. ptrdiff_t offset = 0;
  1732. while ((offset = dwarf_ranges(die, offset, &base, &low, &high)) > 0) {
  1733. if (pc >= low && pc < high) {
  1734. return true;
  1735. }
  1736. }
  1737. return false;
  1738. }
  1739. static Dwarf_Die *find_fundie_by_pc(Dwarf_Die *parent_die, Dwarf_Addr pc,
  1740. Dwarf_Die *result) {
  1741. if (dwarf_child(parent_die, result) != 0) {
  1742. return 0;
  1743. }
  1744. Dwarf_Die *die = result;
  1745. do {
  1746. switch (dwarf_tag(die)) {
  1747. case DW_TAG_subprogram:
  1748. case DW_TAG_inlined_subroutine:
  1749. if (die_has_pc(die, pc)) {
  1750. return result;
  1751. }
  1752. };
  1753. bool declaration = false;
  1754. Dwarf_Attribute attr_mem;
  1755. dwarf_formflag(dwarf_attr(die, DW_AT_declaration, &attr_mem),
  1756. &declaration);
  1757. if (!declaration) {
  1758. // let's be curious and look deeper in the tree,
  1759. // function are not necessarily at the first level, but
  1760. // might be nested inside a namespace, structure etc.
  1761. Dwarf_Die die_mem;
  1762. Dwarf_Die *indie = find_fundie_by_pc(die, pc, &die_mem);
  1763. if (indie) {
  1764. *result = die_mem;
  1765. return result;
  1766. }
  1767. }
  1768. } while (dwarf_siblingof(die, result) == 0);
  1769. return 0;
  1770. }
  1771. template <typename CB>
  1772. static bool deep_first_search_by_pc(Dwarf_Die *parent_die, Dwarf_Addr pc,
  1773. CB cb) {
  1774. Dwarf_Die die_mem;
  1775. if (dwarf_child(parent_die, &die_mem) != 0) {
  1776. return false;
  1777. }
  1778. bool branch_has_pc = false;
  1779. Dwarf_Die *die = &die_mem;
  1780. do {
  1781. bool declaration = false;
  1782. Dwarf_Attribute attr_mem;
  1783. dwarf_formflag(dwarf_attr(die, DW_AT_declaration, &attr_mem),
  1784. &declaration);
  1785. if (!declaration) {
  1786. // let's be curious and look deeper in the tree, function are
  1787. // not necessarily at the first level, but might be nested
  1788. // inside a namespace, structure, a function, an inlined
  1789. // function etc.
  1790. branch_has_pc = deep_first_search_by_pc(die, pc, cb);
  1791. }
  1792. if (!branch_has_pc) {
  1793. branch_has_pc = die_has_pc(die, pc);
  1794. }
  1795. if (branch_has_pc) {
  1796. cb(die);
  1797. }
  1798. } while (dwarf_siblingof(die, &die_mem) == 0);
  1799. return branch_has_pc;
  1800. }
  1801. static const char *die_call_file(Dwarf_Die *die) {
  1802. Dwarf_Attribute attr_mem;
  1803. Dwarf_Word file_idx = 0;
  1804. dwarf_formudata(dwarf_attr(die, DW_AT_call_file, &attr_mem), &file_idx);
  1805. if (file_idx == 0) {
  1806. return 0;
  1807. }
  1808. Dwarf_Die die_mem;
  1809. Dwarf_Die *cudie = dwarf_diecu(die, &die_mem, 0, 0);
  1810. if (!cudie) {
  1811. return 0;
  1812. }
  1813. Dwarf_Files *files = 0;
  1814. size_t nfiles;
  1815. dwarf_getsrcfiles(cudie, &files, &nfiles);
  1816. if (!files) {
  1817. return 0;
  1818. }
  1819. return dwarf_filesrc(files, file_idx, 0, 0);
  1820. }
  1821. };
  1822. #endif // BACKWARD_HAS_DW == 1
  1823. #if BACKWARD_HAS_DWARF == 1
  1824. template <>
  1825. class TraceResolverLinuxImpl<trace_resolver_tag::libdwarf>
  1826. : public TraceResolverLinuxBase {
  1827. public:
  1828. TraceResolverLinuxImpl() : _dwarf_loaded(false) {}
  1829. ResolvedTrace resolve(ResolvedTrace trace) override {
  1830. // trace.addr is a virtual address in memory pointing to some code.
  1831. // Let's try to find from which loaded object it comes from.
  1832. // The loaded object can be yourself btw.
  1833. Dl_info symbol_info;
  1834. int dladdr_result = 0;
  1835. #if defined(__GLIBC__)
  1836. link_map *link_map;
  1837. // We request the link map so we can get information about offsets
  1838. dladdr_result =
  1839. dladdr1(trace.addr, &symbol_info, reinterpret_cast<void **>(&link_map),
  1840. RTLD_DL_LINKMAP);
  1841. #else
  1842. // Android doesn't have dladdr1. Don't use the linker map.
  1843. dladdr_result = dladdr(trace.addr, &symbol_info);
  1844. #endif
  1845. if (!dladdr_result) {
  1846. return trace; // dat broken trace...
  1847. }
  1848. // Now we get in symbol_info:
  1849. // .dli_fname:
  1850. // pathname of the shared object that contains the address.
  1851. // .dli_fbase:
  1852. // where the object is loaded in memory.
  1853. // .dli_sname:
  1854. // the name of the nearest symbol to trace.addr, we expect a
  1855. // function name.
  1856. // .dli_saddr:
  1857. // the exact address corresponding to .dli_sname.
  1858. //
  1859. // And in link_map:
  1860. // .l_addr:
  1861. // difference between the address in the ELF file and the address
  1862. // in memory
  1863. // l_name:
  1864. // absolute pathname where the object was found
  1865. if (symbol_info.dli_sname) {
  1866. trace.object_function = demangle(symbol_info.dli_sname);
  1867. }
  1868. if (!symbol_info.dli_fname) {
  1869. return trace;
  1870. }
  1871. trace.object_filename = resolve_exec_path(symbol_info);
  1872. dwarf_fileobject &fobj = load_object_with_dwarf(symbol_info.dli_fname);
  1873. if (!fobj.dwarf_handle) {
  1874. return trace; // sad, we couldn't load the object :(
  1875. }
  1876. #if defined(__GLIBC__)
  1877. // Convert the address to a module relative one by looking at
  1878. // the module's loading address in the link map
  1879. Dwarf_Addr address = reinterpret_cast<uintptr_t>(trace.addr) -
  1880. reinterpret_cast<uintptr_t>(link_map->l_addr);
  1881. #else
  1882. Dwarf_Addr address = reinterpret_cast<uintptr_t>(trace.addr);
  1883. #endif
  1884. if (trace.object_function.empty()) {
  1885. symbol_cache_t::iterator it = fobj.symbol_cache.lower_bound(address);
  1886. if (it != fobj.symbol_cache.end()) {
  1887. if (it->first != address) {
  1888. if (it != fobj.symbol_cache.begin()) {
  1889. --it;
  1890. }
  1891. }
  1892. trace.object_function = demangle(it->second.c_str());
  1893. }
  1894. }
  1895. // Get the Compilation Unit DIE for the address
  1896. Dwarf_Die die = find_die(fobj, address);
  1897. if (!die) {
  1898. return trace; // this time we lost the game :/
  1899. }
  1900. // libdwarf doesn't give us direct access to its objects, it always
  1901. // allocates a copy for the caller. We keep that copy alive in a cache
  1902. // and we deallocate it later when it's no longer required.
  1903. die_cache_entry &die_object = get_die_cache(fobj, die);
  1904. if (die_object.isEmpty())
  1905. return trace; // We have no line section for this DIE
  1906. die_linemap_t::iterator it = die_object.line_section.lower_bound(address);
  1907. if (it != die_object.line_section.end()) {
  1908. if (it->first != address) {
  1909. if (it == die_object.line_section.begin()) {
  1910. // If we are on the first item of the line section
  1911. // but the address does not match it means that
  1912. // the address is below the range of the DIE. Give up.
  1913. return trace;
  1914. } else {
  1915. --it;
  1916. }
  1917. }
  1918. } else {
  1919. return trace; // We didn't find the address.
  1920. }
  1921. // Get the Dwarf_Line that the address points to and call libdwarf
  1922. // to get source file, line and column info.
  1923. Dwarf_Line line = die_object.line_buffer[it->second];
  1924. Dwarf_Error error = DW_DLE_NE;
  1925. char *filename;
  1926. if (dwarf_linesrc(line, &filename, &error) == DW_DLV_OK) {
  1927. trace.source.filename = std::string(filename);
  1928. dwarf_dealloc(fobj.dwarf_handle.get(), filename, DW_DLA_STRING);
  1929. }
  1930. Dwarf_Unsigned number = 0;
  1931. if (dwarf_lineno(line, &number, &error) == DW_DLV_OK) {
  1932. trace.source.line = number;
  1933. } else {
  1934. trace.source.line = 0;
  1935. }
  1936. if (dwarf_lineoff_b(line, &number, &error) == DW_DLV_OK) {
  1937. trace.source.col = number;
  1938. } else {
  1939. trace.source.col = 0;
  1940. }
  1941. std::vector<std::string> namespace_stack;
  1942. deep_first_search_by_pc(fobj, die, address, namespace_stack,
  1943. inliners_search_cb(trace, fobj, die));
  1944. dwarf_dealloc(fobj.dwarf_handle.get(), die, DW_DLA_DIE);
  1945. return trace;
  1946. }
  1947. public:
  1948. static int close_dwarf(Dwarf_Debug dwarf) {
  1949. return dwarf_finish(dwarf, NULL);
  1950. }
  1951. private:
  1952. bool _dwarf_loaded;
  1953. typedef details::handle<int, details::deleter<int, int, &::close>>
  1954. dwarf_file_t;
  1955. typedef details::handle<Elf *, details::deleter<int, Elf *, &elf_end>>
  1956. dwarf_elf_t;
  1957. typedef details::handle<Dwarf_Debug,
  1958. details::deleter<int, Dwarf_Debug, &close_dwarf>>
  1959. dwarf_handle_t;
  1960. typedef std::map<Dwarf_Addr, int> die_linemap_t;
  1961. typedef std::map<Dwarf_Off, Dwarf_Off> die_specmap_t;
  1962. struct die_cache_entry {
  1963. die_specmap_t spec_section;
  1964. die_linemap_t line_section;
  1965. Dwarf_Line *line_buffer;
  1966. Dwarf_Signed line_count;
  1967. Dwarf_Line_Context line_context;
  1968. inline bool isEmpty() {
  1969. return line_buffer == NULL || line_count == 0 || line_context == NULL ||
  1970. line_section.empty();
  1971. }
  1972. die_cache_entry() : line_buffer(0), line_count(0), line_context(0) {}
  1973. ~die_cache_entry() {
  1974. if (line_context) {
  1975. dwarf_srclines_dealloc_b(line_context);
  1976. }
  1977. }
  1978. };
  1979. typedef std::map<Dwarf_Off, die_cache_entry> die_cache_t;
  1980. typedef std::map<uintptr_t, std::string> symbol_cache_t;
  1981. struct dwarf_fileobject {
  1982. dwarf_file_t file_handle;
  1983. dwarf_elf_t elf_handle;
  1984. dwarf_handle_t dwarf_handle;
  1985. symbol_cache_t symbol_cache;
  1986. // Die cache
  1987. die_cache_t die_cache;
  1988. die_cache_entry *current_cu;
  1989. };
  1990. typedef details::hashtable<std::string, dwarf_fileobject>::type
  1991. fobj_dwarf_map_t;
  1992. fobj_dwarf_map_t _fobj_dwarf_map;
  1993. static bool cstrings_eq(const char *a, const char *b) {
  1994. if (!a || !b) {
  1995. return false;
  1996. }
  1997. return strcmp(a, b) == 0;
  1998. }
  1999. dwarf_fileobject &load_object_with_dwarf(const std::string &filename_object) {
  2000. if (!_dwarf_loaded) {
  2001. // Set the ELF library operating version
  2002. // If that fails there's nothing we can do
  2003. _dwarf_loaded = elf_version(EV_CURRENT) != EV_NONE;
  2004. }
  2005. fobj_dwarf_map_t::iterator it = _fobj_dwarf_map.find(filename_object);
  2006. if (it != _fobj_dwarf_map.end()) {
  2007. return it->second;
  2008. }
  2009. // this new object is empty for now
  2010. dwarf_fileobject &r = _fobj_dwarf_map[filename_object];
  2011. dwarf_file_t file_handle;
  2012. file_handle.reset(open(filename_object.c_str(), O_RDONLY));
  2013. if (file_handle.get() < 0) {
  2014. return r;
  2015. }
  2016. // Try to get an ELF handle. We need to read the ELF sections
  2017. // because we want to see if there is a .gnu_debuglink section
  2018. // that points to a split debug file
  2019. dwarf_elf_t elf_handle;
  2020. elf_handle.reset(elf_begin(file_handle.get(), ELF_C_READ, NULL));
  2021. if (!elf_handle) {
  2022. return r;
  2023. }
  2024. const char *e_ident = elf_getident(elf_handle.get(), 0);
  2025. if (!e_ident) {
  2026. return r;
  2027. }
  2028. // Get the number of sections
  2029. // We use the new APIs as elf_getshnum is deprecated
  2030. size_t shdrnum = 0;
  2031. if (elf_getshdrnum(elf_handle.get(), &shdrnum) == -1) {
  2032. return r;
  2033. }
  2034. // Get the index to the string section
  2035. size_t shdrstrndx = 0;
  2036. if (elf_getshdrstrndx(elf_handle.get(), &shdrstrndx) == -1) {
  2037. return r;
  2038. }
  2039. std::string debuglink;
  2040. // Iterate through the ELF sections to try to get a gnu_debuglink
  2041. // note and also to cache the symbol table.
  2042. // We go the preprocessor way to avoid having to create templated
  2043. // classes or using gelf (which might throw a compiler error if 64 bit
  2044. // is not supported
  2045. #define ELF_GET_DATA(ARCH) \
  2046. Elf_Scn *elf_section = 0; \
  2047. Elf_Data *elf_data = 0; \
  2048. Elf##ARCH##_Shdr *section_header = 0; \
  2049. Elf_Scn *symbol_section = 0; \
  2050. size_t symbol_count = 0; \
  2051. size_t symbol_strings = 0; \
  2052. Elf##ARCH##_Sym *symbol = 0; \
  2053. const char *section_name = 0; \
  2054. \
  2055. while ((elf_section = elf_nextscn(elf_handle.get(), elf_section)) != NULL) { \
  2056. section_header = elf##ARCH##_getshdr(elf_section); \
  2057. if (section_header == NULL) { \
  2058. return r; \
  2059. } \
  2060. \
  2061. if ((section_name = elf_strptr(elf_handle.get(), shdrstrndx, \
  2062. section_header->sh_name)) == NULL) { \
  2063. return r; \
  2064. } \
  2065. \
  2066. if (cstrings_eq(section_name, ".gnu_debuglink")) { \
  2067. elf_data = elf_getdata(elf_section, NULL); \
  2068. if (elf_data && elf_data->d_size > 0) { \
  2069. debuglink = \
  2070. std::string(reinterpret_cast<const char *>(elf_data->d_buf)); \
  2071. } \
  2072. } \
  2073. \
  2074. switch (section_header->sh_type) { \
  2075. case SHT_SYMTAB: \
  2076. symbol_section = elf_section; \
  2077. symbol_count = section_header->sh_size / section_header->sh_entsize; \
  2078. symbol_strings = section_header->sh_link; \
  2079. break; \
  2080. \
  2081. /* We use .dynsyms as a last resort, we prefer .symtab */ \
  2082. case SHT_DYNSYM: \
  2083. if (!symbol_section) { \
  2084. symbol_section = elf_section; \
  2085. symbol_count = section_header->sh_size / section_header->sh_entsize; \
  2086. symbol_strings = section_header->sh_link; \
  2087. } \
  2088. break; \
  2089. } \
  2090. } \
  2091. \
  2092. if (symbol_section && symbol_count && symbol_strings) { \
  2093. elf_data = elf_getdata(symbol_section, NULL); \
  2094. symbol = reinterpret_cast<Elf##ARCH##_Sym *>(elf_data->d_buf); \
  2095. for (size_t i = 0; i < symbol_count; ++i) { \
  2096. int type = ELF##ARCH##_ST_TYPE(symbol->st_info); \
  2097. if (type == STT_FUNC && symbol->st_value > 0) { \
  2098. r.symbol_cache[symbol->st_value] = std::string( \
  2099. elf_strptr(elf_handle.get(), symbol_strings, symbol->st_name)); \
  2100. } \
  2101. ++symbol; \
  2102. } \
  2103. }
  2104. if (e_ident[EI_CLASS] == ELFCLASS32) {
  2105. ELF_GET_DATA(32)
  2106. } else if (e_ident[EI_CLASS] == ELFCLASS64) {
  2107. // libelf might have been built without 64 bit support
  2108. #if __LIBELF64
  2109. ELF_GET_DATA(64)
  2110. #endif
  2111. }
  2112. if (!debuglink.empty()) {
  2113. // We have a debuglink section! Open an elf instance on that
  2114. // file instead. If we can't open the file, then return
  2115. // the elf handle we had already opened.
  2116. dwarf_file_t debuglink_file;
  2117. debuglink_file.reset(open(debuglink.c_str(), O_RDONLY));
  2118. if (debuglink_file.get() > 0) {
  2119. dwarf_elf_t debuglink_elf;
  2120. debuglink_elf.reset(elf_begin(debuglink_file.get(), ELF_C_READ, NULL));
  2121. // If we have a valid elf handle, return the new elf handle
  2122. // and file handle and discard the original ones
  2123. if (debuglink_elf) {
  2124. elf_handle = move(debuglink_elf);
  2125. file_handle = move(debuglink_file);
  2126. }
  2127. }
  2128. }
  2129. // Ok, we have a valid ELF handle, let's try to get debug symbols
  2130. Dwarf_Debug dwarf_debug;
  2131. Dwarf_Error error = DW_DLE_NE;
  2132. dwarf_handle_t dwarf_handle;
  2133. int dwarf_result = dwarf_elf_init(elf_handle.get(), DW_DLC_READ, NULL, NULL,
  2134. &dwarf_debug, &error);
  2135. // We don't do any special handling for DW_DLV_NO_ENTRY specially.
  2136. // If we get an error, or the file doesn't have debug information
  2137. // we just return.
  2138. if (dwarf_result != DW_DLV_OK) {
  2139. return r;
  2140. }
  2141. dwarf_handle.reset(dwarf_debug);
  2142. r.file_handle = move(file_handle);
  2143. r.elf_handle = move(elf_handle);
  2144. r.dwarf_handle = move(dwarf_handle);
  2145. return r;
  2146. }
  2147. die_cache_entry &get_die_cache(dwarf_fileobject &fobj, Dwarf_Die die) {
  2148. Dwarf_Error error = DW_DLE_NE;
  2149. // Get the die offset, we use it as the cache key
  2150. Dwarf_Off die_offset;
  2151. if (dwarf_dieoffset(die, &die_offset, &error) != DW_DLV_OK) {
  2152. die_offset = 0;
  2153. }
  2154. die_cache_t::iterator it = fobj.die_cache.find(die_offset);
  2155. if (it != fobj.die_cache.end()) {
  2156. fobj.current_cu = &it->second;
  2157. return it->second;
  2158. }
  2159. die_cache_entry &de = fobj.die_cache[die_offset];
  2160. fobj.current_cu = &de;
  2161. Dwarf_Addr line_addr;
  2162. Dwarf_Small table_count;
  2163. // The addresses in the line section are not fully sorted (they might
  2164. // be sorted by block of code belonging to the same file), which makes
  2165. // it necessary to do so before searching is possible.
  2166. //
  2167. // As libdwarf allocates a copy of everything, let's get the contents
  2168. // of the line section and keep it around. We also create a map of
  2169. // program counter to line table indices so we can search by address
  2170. // and get the line buffer index.
  2171. //
  2172. // To make things more difficult, the same address can span more than
  2173. // one line, so we need to keep the index pointing to the first line
  2174. // by using insert instead of the map's [ operator.
  2175. // Get the line context for the DIE
  2176. if (dwarf_srclines_b(die, 0, &table_count, &de.line_context, &error) ==
  2177. DW_DLV_OK) {
  2178. // Get the source lines for this line context, to be deallocated
  2179. // later
  2180. if (dwarf_srclines_from_linecontext(de.line_context, &de.line_buffer,
  2181. &de.line_count,
  2182. &error) == DW_DLV_OK) {
  2183. // Add all the addresses to our map
  2184. for (int i = 0; i < de.line_count; i++) {
  2185. if (dwarf_lineaddr(de.line_buffer[i], &line_addr, &error) !=
  2186. DW_DLV_OK) {
  2187. line_addr = 0;
  2188. }
  2189. de.line_section.insert(std::pair<Dwarf_Addr, int>(line_addr, i));
  2190. }
  2191. }
  2192. }
  2193. // For each CU, cache the function DIEs that contain the
  2194. // DW_AT_specification attribute. When building with -g3 the function
  2195. // DIEs are separated in declaration and specification, with the
  2196. // declaration containing only the name and parameters and the
  2197. // specification the low/high pc and other compiler attributes.
  2198. //
  2199. // We cache those specifications so we don't skip over the declarations,
  2200. // because they have no pc, and we can do namespace resolution for
  2201. // DWARF function names.
  2202. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2203. Dwarf_Die current_die = 0;
  2204. if (dwarf_child(die, &current_die, &error) == DW_DLV_OK) {
  2205. for (;;) {
  2206. Dwarf_Die sibling_die = 0;
  2207. Dwarf_Half tag_value;
  2208. dwarf_tag(current_die, &tag_value, &error);
  2209. if (tag_value == DW_TAG_subprogram ||
  2210. tag_value == DW_TAG_inlined_subroutine) {
  2211. Dwarf_Bool has_attr = 0;
  2212. if (dwarf_hasattr(current_die, DW_AT_specification, &has_attr,
  2213. &error) == DW_DLV_OK) {
  2214. if (has_attr) {
  2215. Dwarf_Attribute attr_mem;
  2216. if (dwarf_attr(current_die, DW_AT_specification, &attr_mem,
  2217. &error) == DW_DLV_OK) {
  2218. Dwarf_Off spec_offset = 0;
  2219. if (dwarf_formref(attr_mem, &spec_offset, &error) ==
  2220. DW_DLV_OK) {
  2221. Dwarf_Off spec_die_offset;
  2222. if (dwarf_dieoffset(current_die, &spec_die_offset, &error) ==
  2223. DW_DLV_OK) {
  2224. de.spec_section[spec_offset] = spec_die_offset;
  2225. }
  2226. }
  2227. }
  2228. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2229. }
  2230. }
  2231. }
  2232. int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error);
  2233. if (result == DW_DLV_ERROR) {
  2234. break;
  2235. } else if (result == DW_DLV_NO_ENTRY) {
  2236. break;
  2237. }
  2238. if (current_die != die) {
  2239. dwarf_dealloc(dwarf, current_die, DW_DLA_DIE);
  2240. current_die = 0;
  2241. }
  2242. current_die = sibling_die;
  2243. }
  2244. }
  2245. return de;
  2246. }
  2247. static Dwarf_Die get_referenced_die(Dwarf_Debug dwarf, Dwarf_Die die,
  2248. Dwarf_Half attr, bool global) {
  2249. Dwarf_Error error = DW_DLE_NE;
  2250. Dwarf_Attribute attr_mem;
  2251. Dwarf_Die found_die = NULL;
  2252. if (dwarf_attr(die, attr, &attr_mem, &error) == DW_DLV_OK) {
  2253. Dwarf_Off offset;
  2254. int result = 0;
  2255. if (global) {
  2256. result = dwarf_global_formref(attr_mem, &offset, &error);
  2257. } else {
  2258. result = dwarf_formref(attr_mem, &offset, &error);
  2259. }
  2260. if (result == DW_DLV_OK) {
  2261. if (dwarf_offdie(dwarf, offset, &found_die, &error) != DW_DLV_OK) {
  2262. found_die = NULL;
  2263. }
  2264. }
  2265. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2266. }
  2267. return found_die;
  2268. }
  2269. static std::string get_referenced_die_name(Dwarf_Debug dwarf, Dwarf_Die die,
  2270. Dwarf_Half attr, bool global) {
  2271. Dwarf_Error error = DW_DLE_NE;
  2272. std::string value;
  2273. Dwarf_Die found_die = get_referenced_die(dwarf, die, attr, global);
  2274. if (found_die) {
  2275. char *name;
  2276. if (dwarf_diename(found_die, &name, &error) == DW_DLV_OK) {
  2277. if (name) {
  2278. value = std::string(name);
  2279. }
  2280. dwarf_dealloc(dwarf, name, DW_DLA_STRING);
  2281. }
  2282. dwarf_dealloc(dwarf, found_die, DW_DLA_DIE);
  2283. }
  2284. return value;
  2285. }
  2286. // Returns a spec DIE linked to the passed one. The caller should
  2287. // deallocate the DIE
  2288. static Dwarf_Die get_spec_die(dwarf_fileobject &fobj, Dwarf_Die die) {
  2289. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2290. Dwarf_Error error = DW_DLE_NE;
  2291. Dwarf_Off die_offset;
  2292. if (fobj.current_cu &&
  2293. dwarf_die_CU_offset(die, &die_offset, &error) == DW_DLV_OK) {
  2294. die_specmap_t::iterator it =
  2295. fobj.current_cu->spec_section.find(die_offset);
  2296. // If we have a DIE that completes the current one, check if
  2297. // that one has the pc we are looking for
  2298. if (it != fobj.current_cu->spec_section.end()) {
  2299. Dwarf_Die spec_die = 0;
  2300. if (dwarf_offdie(dwarf, it->second, &spec_die, &error) == DW_DLV_OK) {
  2301. return spec_die;
  2302. }
  2303. }
  2304. }
  2305. // Maybe we have an abstract origin DIE with the function information?
  2306. return get_referenced_die(fobj.dwarf_handle.get(), die,
  2307. DW_AT_abstract_origin, true);
  2308. }
  2309. static bool die_has_pc(dwarf_fileobject &fobj, Dwarf_Die die, Dwarf_Addr pc) {
  2310. Dwarf_Addr low_pc = 0, high_pc = 0;
  2311. Dwarf_Half high_pc_form = 0;
  2312. Dwarf_Form_Class return_class;
  2313. Dwarf_Error error = DW_DLE_NE;
  2314. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2315. bool has_lowpc = false;
  2316. bool has_highpc = false;
  2317. bool has_ranges = false;
  2318. if (dwarf_lowpc(die, &low_pc, &error) == DW_DLV_OK) {
  2319. // If we have a low_pc check if there is a high pc.
  2320. // If we don't have a high pc this might mean we have a base
  2321. // address for the ranges list or just an address.
  2322. has_lowpc = true;
  2323. if (dwarf_highpc_b(die, &high_pc, &high_pc_form, &return_class, &error) ==
  2324. DW_DLV_OK) {
  2325. // We do have a high pc. In DWARF 4+ this is an offset from the
  2326. // low pc, but in earlier versions it's an absolute address.
  2327. has_highpc = true;
  2328. // In DWARF 2/3 this would be a DW_FORM_CLASS_ADDRESS
  2329. if (return_class == DW_FORM_CLASS_CONSTANT) {
  2330. high_pc = low_pc + high_pc;
  2331. }
  2332. // We have low and high pc, check if our address
  2333. // is in that range
  2334. return pc >= low_pc && pc < high_pc;
  2335. }
  2336. } else {
  2337. // Reset the low_pc, in case dwarf_lowpc failing set it to some
  2338. // undefined value.
  2339. low_pc = 0;
  2340. }
  2341. // Check if DW_AT_ranges is present and search for the PC in the
  2342. // returned ranges list. We always add the low_pc, as it not set it will
  2343. // be 0, in case we had a DW_AT_low_pc and DW_AT_ranges pair
  2344. bool result = false;
  2345. Dwarf_Attribute attr;
  2346. if (dwarf_attr(die, DW_AT_ranges, &attr, &error) == DW_DLV_OK) {
  2347. Dwarf_Off offset;
  2348. if (dwarf_global_formref(attr, &offset, &error) == DW_DLV_OK) {
  2349. Dwarf_Ranges *ranges;
  2350. Dwarf_Signed ranges_count = 0;
  2351. Dwarf_Unsigned byte_count = 0;
  2352. if (dwarf_get_ranges_a(dwarf, offset, die, &ranges, &ranges_count,
  2353. &byte_count, &error) == DW_DLV_OK) {
  2354. has_ranges = ranges_count != 0;
  2355. for (int i = 0; i < ranges_count; i++) {
  2356. if (ranges[i].dwr_addr1 != 0 &&
  2357. pc >= ranges[i].dwr_addr1 + low_pc &&
  2358. pc < ranges[i].dwr_addr2 + low_pc) {
  2359. result = true;
  2360. break;
  2361. }
  2362. }
  2363. dwarf_ranges_dealloc(dwarf, ranges, ranges_count);
  2364. }
  2365. }
  2366. }
  2367. // Last attempt. We might have a single address set as low_pc.
  2368. if (!result && low_pc != 0 && pc == low_pc) {
  2369. result = true;
  2370. }
  2371. // If we don't have lowpc, highpc and ranges maybe this DIE is a
  2372. // declaration that relies on a DW_AT_specification DIE that happens
  2373. // later. Use the specification cache we filled when we loaded this CU.
  2374. if (!result && (!has_lowpc && !has_highpc && !has_ranges)) {
  2375. Dwarf_Die spec_die = get_spec_die(fobj, die);
  2376. if (spec_die) {
  2377. result = die_has_pc(fobj, spec_die, pc);
  2378. dwarf_dealloc(dwarf, spec_die, DW_DLA_DIE);
  2379. }
  2380. }
  2381. return result;
  2382. }
  2383. static void get_type(Dwarf_Debug dwarf, Dwarf_Die die, std::string &type) {
  2384. Dwarf_Error error = DW_DLE_NE;
  2385. Dwarf_Die child = 0;
  2386. if (dwarf_child(die, &child, &error) == DW_DLV_OK) {
  2387. get_type(dwarf, child, type);
  2388. }
  2389. if (child) {
  2390. type.insert(0, "::");
  2391. dwarf_dealloc(dwarf, child, DW_DLA_DIE);
  2392. }
  2393. char *name;
  2394. if (dwarf_diename(die, &name, &error) == DW_DLV_OK) {
  2395. type.insert(0, std::string(name));
  2396. dwarf_dealloc(dwarf, name, DW_DLA_STRING);
  2397. } else {
  2398. type.insert(0, "<unknown>");
  2399. }
  2400. }
  2401. static std::string get_type_by_signature(Dwarf_Debug dwarf, Dwarf_Die die) {
  2402. Dwarf_Error error = DW_DLE_NE;
  2403. Dwarf_Sig8 signature;
  2404. Dwarf_Bool has_attr = 0;
  2405. if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) == DW_DLV_OK) {
  2406. if (has_attr) {
  2407. Dwarf_Attribute attr_mem;
  2408. if (dwarf_attr(die, DW_AT_signature, &attr_mem, &error) == DW_DLV_OK) {
  2409. if (dwarf_formsig8(attr_mem, &signature, &error) != DW_DLV_OK) {
  2410. return std::string("<no type signature>");
  2411. }
  2412. }
  2413. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2414. }
  2415. }
  2416. Dwarf_Unsigned next_cu_header;
  2417. Dwarf_Sig8 tu_signature;
  2418. std::string result;
  2419. bool found = false;
  2420. while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, &tu_signature, 0,
  2421. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2422. if (strncmp(signature.signature, tu_signature.signature, 8) == 0) {
  2423. Dwarf_Die type_cu_die = 0;
  2424. if (dwarf_siblingof_b(dwarf, 0, 0, &type_cu_die, &error) == DW_DLV_OK) {
  2425. Dwarf_Die child_die = 0;
  2426. if (dwarf_child(type_cu_die, &child_die, &error) == DW_DLV_OK) {
  2427. get_type(dwarf, child_die, result);
  2428. found = !result.empty();
  2429. dwarf_dealloc(dwarf, child_die, DW_DLA_DIE);
  2430. }
  2431. dwarf_dealloc(dwarf, type_cu_die, DW_DLA_DIE);
  2432. }
  2433. }
  2434. }
  2435. if (found) {
  2436. while (dwarf_next_cu_header_d(dwarf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2437. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2438. // Reset the cu header state. Unfortunately, libdwarf's
  2439. // next_cu_header API keeps its own iterator per Dwarf_Debug
  2440. // that can't be reset. We need to keep fetching elements until
  2441. // the end.
  2442. }
  2443. } else {
  2444. // If we couldn't resolve the type just print out the signature
  2445. std::ostringstream string_stream;
  2446. string_stream << "<0x" << std::hex << std::setfill('0');
  2447. for (int i = 0; i < 8; ++i) {
  2448. string_stream << std::setw(2) << std::hex
  2449. << (int)(unsigned char)(signature.signature[i]);
  2450. }
  2451. string_stream << ">";
  2452. result = string_stream.str();
  2453. }
  2454. return result;
  2455. }
  2456. struct type_context_t {
  2457. bool is_const;
  2458. bool is_typedef;
  2459. bool has_type;
  2460. bool has_name;
  2461. std::string text;
  2462. type_context_t()
  2463. : is_const(false), is_typedef(false), has_type(false), has_name(false) {
  2464. }
  2465. };
  2466. // Types are resolved from right to left: we get the variable name first
  2467. // and then all specifiers (like const or pointer) in a chain of DW_AT_type
  2468. // DIEs. Call this function recursively until we get a complete type
  2469. // string.
  2470. static void set_parameter_string(dwarf_fileobject &fobj, Dwarf_Die die,
  2471. type_context_t &context) {
  2472. char *name;
  2473. Dwarf_Error error = DW_DLE_NE;
  2474. // typedefs contain also the base type, so we skip it and only
  2475. // print the typedef name
  2476. if (!context.is_typedef) {
  2477. if (dwarf_diename(die, &name, &error) == DW_DLV_OK) {
  2478. if (!context.text.empty()) {
  2479. context.text.insert(0, " ");
  2480. }
  2481. context.text.insert(0, std::string(name));
  2482. dwarf_dealloc(fobj.dwarf_handle.get(), name, DW_DLA_STRING);
  2483. }
  2484. } else {
  2485. context.is_typedef = false;
  2486. context.has_type = true;
  2487. if (context.is_const) {
  2488. context.text.insert(0, "const ");
  2489. context.is_const = false;
  2490. }
  2491. }
  2492. bool next_type_is_const = false;
  2493. bool is_keyword = true;
  2494. Dwarf_Half tag = 0;
  2495. Dwarf_Bool has_attr = 0;
  2496. if (dwarf_tag(die, &tag, &error) == DW_DLV_OK) {
  2497. switch (tag) {
  2498. case DW_TAG_structure_type:
  2499. case DW_TAG_union_type:
  2500. case DW_TAG_class_type:
  2501. case DW_TAG_enumeration_type:
  2502. context.has_type = true;
  2503. if (dwarf_hasattr(die, DW_AT_signature, &has_attr, &error) ==
  2504. DW_DLV_OK) {
  2505. // If we have a signature it means the type is defined
  2506. // in .debug_types, so we need to load the DIE pointed
  2507. // at by the signature and resolve it
  2508. if (has_attr) {
  2509. std::string type =
  2510. get_type_by_signature(fobj.dwarf_handle.get(), die);
  2511. if (context.is_const)
  2512. type.insert(0, "const ");
  2513. if (!context.text.empty())
  2514. context.text.insert(0, " ");
  2515. context.text.insert(0, type);
  2516. }
  2517. // Treat enums like typedefs, and skip printing its
  2518. // base type
  2519. context.is_typedef = (tag == DW_TAG_enumeration_type);
  2520. }
  2521. break;
  2522. case DW_TAG_const_type:
  2523. next_type_is_const = true;
  2524. break;
  2525. case DW_TAG_pointer_type:
  2526. context.text.insert(0, "*");
  2527. break;
  2528. case DW_TAG_reference_type:
  2529. context.text.insert(0, "&");
  2530. break;
  2531. case DW_TAG_restrict_type:
  2532. context.text.insert(0, "restrict ");
  2533. break;
  2534. case DW_TAG_rvalue_reference_type:
  2535. context.text.insert(0, "&&");
  2536. break;
  2537. case DW_TAG_volatile_type:
  2538. context.text.insert(0, "volatile ");
  2539. break;
  2540. case DW_TAG_typedef:
  2541. // Propagate the const-ness to the next type
  2542. // as typedefs are linked to its base type
  2543. next_type_is_const = context.is_const;
  2544. context.is_typedef = true;
  2545. context.has_type = true;
  2546. break;
  2547. case DW_TAG_base_type:
  2548. context.has_type = true;
  2549. break;
  2550. case DW_TAG_formal_parameter:
  2551. context.has_name = true;
  2552. break;
  2553. default:
  2554. is_keyword = false;
  2555. break;
  2556. }
  2557. }
  2558. if (!is_keyword && context.is_const) {
  2559. context.text.insert(0, "const ");
  2560. }
  2561. context.is_const = next_type_is_const;
  2562. Dwarf_Die ref =
  2563. get_referenced_die(fobj.dwarf_handle.get(), die, DW_AT_type, true);
  2564. if (ref) {
  2565. set_parameter_string(fobj, ref, context);
  2566. dwarf_dealloc(fobj.dwarf_handle.get(), ref, DW_DLA_DIE);
  2567. }
  2568. if (!context.has_type && context.has_name) {
  2569. context.text.insert(0, "void ");
  2570. context.has_type = true;
  2571. }
  2572. }
  2573. // Resolve the function return type and parameters
  2574. static void set_function_parameters(std::string &function_name,
  2575. std::vector<std::string> &ns,
  2576. dwarf_fileobject &fobj, Dwarf_Die die) {
  2577. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2578. Dwarf_Error error = DW_DLE_NE;
  2579. Dwarf_Die current_die = 0;
  2580. std::string parameters;
  2581. bool has_spec = true;
  2582. // Check if we have a spec DIE. If we do we use it as it contains
  2583. // more information, like parameter names.
  2584. Dwarf_Die spec_die = get_spec_die(fobj, die);
  2585. if (!spec_die) {
  2586. has_spec = false;
  2587. spec_die = die;
  2588. }
  2589. std::vector<std::string>::const_iterator it = ns.begin();
  2590. std::string ns_name;
  2591. for (it = ns.begin(); it < ns.end(); ++it) {
  2592. ns_name.append(*it).append("::");
  2593. }
  2594. if (!ns_name.empty()) {
  2595. function_name.insert(0, ns_name);
  2596. }
  2597. // See if we have a function return type. It can be either on the
  2598. // current die or in its spec one (usually true for inlined functions)
  2599. std::string return_type =
  2600. get_referenced_die_name(dwarf, die, DW_AT_type, true);
  2601. if (return_type.empty()) {
  2602. return_type = get_referenced_die_name(dwarf, spec_die, DW_AT_type, true);
  2603. }
  2604. if (!return_type.empty()) {
  2605. return_type.append(" ");
  2606. function_name.insert(0, return_type);
  2607. }
  2608. if (dwarf_child(spec_die, &current_die, &error) == DW_DLV_OK) {
  2609. for (;;) {
  2610. Dwarf_Die sibling_die = 0;
  2611. Dwarf_Half tag_value;
  2612. dwarf_tag(current_die, &tag_value, &error);
  2613. if (tag_value == DW_TAG_formal_parameter) {
  2614. // Ignore artificial (ie, compiler generated) parameters
  2615. bool is_artificial = false;
  2616. Dwarf_Attribute attr_mem;
  2617. if (dwarf_attr(current_die, DW_AT_artificial, &attr_mem, &error) ==
  2618. DW_DLV_OK) {
  2619. Dwarf_Bool flag = 0;
  2620. if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) {
  2621. is_artificial = flag != 0;
  2622. }
  2623. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2624. }
  2625. if (!is_artificial) {
  2626. type_context_t context;
  2627. set_parameter_string(fobj, current_die, context);
  2628. if (parameters.empty()) {
  2629. parameters.append("(");
  2630. } else {
  2631. parameters.append(", ");
  2632. }
  2633. parameters.append(context.text);
  2634. }
  2635. }
  2636. int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error);
  2637. if (result == DW_DLV_ERROR) {
  2638. break;
  2639. } else if (result == DW_DLV_NO_ENTRY) {
  2640. break;
  2641. }
  2642. if (current_die != die) {
  2643. dwarf_dealloc(dwarf, current_die, DW_DLA_DIE);
  2644. current_die = 0;
  2645. }
  2646. current_die = sibling_die;
  2647. }
  2648. }
  2649. if (parameters.empty())
  2650. parameters = "(";
  2651. parameters.append(")");
  2652. // If we got a spec DIE we need to deallocate it
  2653. if (has_spec)
  2654. dwarf_dealloc(dwarf, spec_die, DW_DLA_DIE);
  2655. function_name.append(parameters);
  2656. }
  2657. // defined here because in C++98, template function cannot take locally
  2658. // defined types... grrr.
  2659. struct inliners_search_cb {
  2660. void operator()(Dwarf_Die die, std::vector<std::string> &ns) {
  2661. Dwarf_Error error = DW_DLE_NE;
  2662. Dwarf_Half tag_value;
  2663. Dwarf_Attribute attr_mem;
  2664. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2665. dwarf_tag(die, &tag_value, &error);
  2666. switch (tag_value) {
  2667. char *name;
  2668. case DW_TAG_subprogram:
  2669. if (!trace.source.function.empty())
  2670. break;
  2671. if (dwarf_diename(die, &name, &error) == DW_DLV_OK) {
  2672. trace.source.function = std::string(name);
  2673. dwarf_dealloc(dwarf, name, DW_DLA_STRING);
  2674. } else {
  2675. // We don't have a function name in this DIE.
  2676. // Check if there is a referenced non-defining
  2677. // declaration.
  2678. trace.source.function =
  2679. get_referenced_die_name(dwarf, die, DW_AT_abstract_origin, true);
  2680. if (trace.source.function.empty()) {
  2681. trace.source.function =
  2682. get_referenced_die_name(dwarf, die, DW_AT_specification, true);
  2683. }
  2684. }
  2685. // Append the function parameters, if available
  2686. set_function_parameters(trace.source.function, ns, fobj, die);
  2687. // If the object function name is empty, it's possible that
  2688. // there is no dynamic symbol table (maybe the executable
  2689. // was stripped or not built with -rdynamic). See if we have
  2690. // a DWARF linkage name to use instead. We try both
  2691. // linkage_name and MIPS_linkage_name because the MIPS tag
  2692. // was the unofficial one until it was adopted in DWARF4.
  2693. // Old gcc versions generate MIPS_linkage_name
  2694. if (trace.object_function.empty()) {
  2695. details::demangler demangler;
  2696. if (dwarf_attr(die, DW_AT_linkage_name, &attr_mem, &error) !=
  2697. DW_DLV_OK) {
  2698. if (dwarf_attr(die, DW_AT_MIPS_linkage_name, &attr_mem, &error) !=
  2699. DW_DLV_OK) {
  2700. break;
  2701. }
  2702. }
  2703. char *linkage;
  2704. if (dwarf_formstring(attr_mem, &linkage, &error) == DW_DLV_OK) {
  2705. trace.object_function = demangler.demangle(linkage);
  2706. dwarf_dealloc(dwarf, linkage, DW_DLA_STRING);
  2707. }
  2708. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2709. }
  2710. break;
  2711. case DW_TAG_inlined_subroutine:
  2712. ResolvedTrace::SourceLoc sloc;
  2713. if (dwarf_diename(die, &name, &error) == DW_DLV_OK) {
  2714. sloc.function = std::string(name);
  2715. dwarf_dealloc(dwarf, name, DW_DLA_STRING);
  2716. } else {
  2717. // We don't have a name for this inlined DIE, it could
  2718. // be that there is an abstract origin instead.
  2719. // Get the DW_AT_abstract_origin value, which is a
  2720. // reference to the source DIE and try to get its name
  2721. sloc.function =
  2722. get_referenced_die_name(dwarf, die, DW_AT_abstract_origin, true);
  2723. }
  2724. set_function_parameters(sloc.function, ns, fobj, die);
  2725. std::string file = die_call_file(dwarf, die, cu_die);
  2726. if (!file.empty())
  2727. sloc.filename = file;
  2728. Dwarf_Unsigned number = 0;
  2729. if (dwarf_attr(die, DW_AT_call_line, &attr_mem, &error) == DW_DLV_OK) {
  2730. if (dwarf_formudata(attr_mem, &number, &error) == DW_DLV_OK) {
  2731. sloc.line = number;
  2732. }
  2733. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2734. }
  2735. if (dwarf_attr(die, DW_AT_call_column, &attr_mem, &error) ==
  2736. DW_DLV_OK) {
  2737. if (dwarf_formudata(attr_mem, &number, &error) == DW_DLV_OK) {
  2738. sloc.col = number;
  2739. }
  2740. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2741. }
  2742. trace.inliners.push_back(sloc);
  2743. break;
  2744. };
  2745. }
  2746. ResolvedTrace &trace;
  2747. dwarf_fileobject &fobj;
  2748. Dwarf_Die cu_die;
  2749. inliners_search_cb(ResolvedTrace &t, dwarf_fileobject &f, Dwarf_Die c)
  2750. : trace(t), fobj(f), cu_die(c) {}
  2751. };
  2752. static Dwarf_Die find_fundie_by_pc(dwarf_fileobject &fobj,
  2753. Dwarf_Die parent_die, Dwarf_Addr pc,
  2754. Dwarf_Die result) {
  2755. Dwarf_Die current_die = 0;
  2756. Dwarf_Error error = DW_DLE_NE;
  2757. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2758. if (dwarf_child(parent_die, &current_die, &error) != DW_DLV_OK) {
  2759. return NULL;
  2760. }
  2761. for (;;) {
  2762. Dwarf_Die sibling_die = 0;
  2763. Dwarf_Half tag_value;
  2764. dwarf_tag(current_die, &tag_value, &error);
  2765. switch (tag_value) {
  2766. case DW_TAG_subprogram:
  2767. case DW_TAG_inlined_subroutine:
  2768. if (die_has_pc(fobj, current_die, pc)) {
  2769. return current_die;
  2770. }
  2771. };
  2772. bool declaration = false;
  2773. Dwarf_Attribute attr_mem;
  2774. if (dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) ==
  2775. DW_DLV_OK) {
  2776. Dwarf_Bool flag = 0;
  2777. if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) {
  2778. declaration = flag != 0;
  2779. }
  2780. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2781. }
  2782. if (!declaration) {
  2783. // let's be curious and look deeper in the tree, functions are
  2784. // not necessarily at the first level, but might be nested
  2785. // inside a namespace, structure, a function, an inlined
  2786. // function etc.
  2787. Dwarf_Die die_mem = 0;
  2788. Dwarf_Die indie = find_fundie_by_pc(fobj, current_die, pc, die_mem);
  2789. if (indie) {
  2790. result = die_mem;
  2791. return result;
  2792. }
  2793. }
  2794. int res = dwarf_siblingof(dwarf, current_die, &sibling_die, &error);
  2795. if (res == DW_DLV_ERROR) {
  2796. return NULL;
  2797. } else if (res == DW_DLV_NO_ENTRY) {
  2798. break;
  2799. }
  2800. if (current_die != parent_die) {
  2801. dwarf_dealloc(dwarf, current_die, DW_DLA_DIE);
  2802. current_die = 0;
  2803. }
  2804. current_die = sibling_die;
  2805. }
  2806. return NULL;
  2807. }
  2808. template <typename CB>
  2809. static bool deep_first_search_by_pc(dwarf_fileobject &fobj,
  2810. Dwarf_Die parent_die, Dwarf_Addr pc,
  2811. std::vector<std::string> &ns, CB cb) {
  2812. Dwarf_Die current_die = 0;
  2813. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2814. Dwarf_Error error = DW_DLE_NE;
  2815. if (dwarf_child(parent_die, &current_die, &error) != DW_DLV_OK) {
  2816. return false;
  2817. }
  2818. bool branch_has_pc = false;
  2819. bool has_namespace = false;
  2820. for (;;) {
  2821. Dwarf_Die sibling_die = 0;
  2822. Dwarf_Half tag;
  2823. if (dwarf_tag(current_die, &tag, &error) == DW_DLV_OK) {
  2824. if (tag == DW_TAG_namespace || tag == DW_TAG_class_type) {
  2825. char *ns_name = NULL;
  2826. if (dwarf_diename(current_die, &ns_name, &error) == DW_DLV_OK) {
  2827. if (ns_name) {
  2828. ns.push_back(std::string(ns_name));
  2829. } else {
  2830. ns.push_back("<unknown>");
  2831. }
  2832. dwarf_dealloc(dwarf, ns_name, DW_DLA_STRING);
  2833. } else {
  2834. ns.push_back("<unknown>");
  2835. }
  2836. has_namespace = true;
  2837. }
  2838. }
  2839. bool declaration = false;
  2840. Dwarf_Attribute attr_mem;
  2841. if (tag != DW_TAG_class_type &&
  2842. dwarf_attr(current_die, DW_AT_declaration, &attr_mem, &error) ==
  2843. DW_DLV_OK) {
  2844. Dwarf_Bool flag = 0;
  2845. if (dwarf_formflag(attr_mem, &flag, &error) == DW_DLV_OK) {
  2846. declaration = flag != 0;
  2847. }
  2848. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2849. }
  2850. if (!declaration) {
  2851. // let's be curious and look deeper in the tree, function are
  2852. // not necessarily at the first level, but might be nested
  2853. // inside a namespace, structure, a function, an inlined
  2854. // function etc.
  2855. branch_has_pc = deep_first_search_by_pc(fobj, current_die, pc, ns, cb);
  2856. }
  2857. if (!branch_has_pc) {
  2858. branch_has_pc = die_has_pc(fobj, current_die, pc);
  2859. }
  2860. if (branch_has_pc) {
  2861. cb(current_die, ns);
  2862. }
  2863. int result = dwarf_siblingof(dwarf, current_die, &sibling_die, &error);
  2864. if (result == DW_DLV_ERROR) {
  2865. return false;
  2866. } else if (result == DW_DLV_NO_ENTRY) {
  2867. break;
  2868. }
  2869. if (current_die != parent_die) {
  2870. dwarf_dealloc(dwarf, current_die, DW_DLA_DIE);
  2871. current_die = 0;
  2872. }
  2873. if (has_namespace) {
  2874. has_namespace = false;
  2875. ns.pop_back();
  2876. }
  2877. current_die = sibling_die;
  2878. }
  2879. if (has_namespace) {
  2880. ns.pop_back();
  2881. }
  2882. return branch_has_pc;
  2883. }
  2884. static std::string die_call_file(Dwarf_Debug dwarf, Dwarf_Die die,
  2885. Dwarf_Die cu_die) {
  2886. Dwarf_Attribute attr_mem;
  2887. Dwarf_Error error = DW_DLE_NE;
  2888. Dwarf_Unsigned file_index;
  2889. std::string file;
  2890. if (dwarf_attr(die, DW_AT_call_file, &attr_mem, &error) == DW_DLV_OK) {
  2891. if (dwarf_formudata(attr_mem, &file_index, &error) != DW_DLV_OK) {
  2892. file_index = 0;
  2893. }
  2894. dwarf_dealloc(dwarf, attr_mem, DW_DLA_ATTR);
  2895. if (file_index == 0) {
  2896. return file;
  2897. }
  2898. char **srcfiles = 0;
  2899. Dwarf_Signed file_count = 0;
  2900. if (dwarf_srcfiles(cu_die, &srcfiles, &file_count, &error) == DW_DLV_OK) {
  2901. if (file_count > 0 && file_index <= static_cast<Dwarf_Unsigned>(file_count)) {
  2902. file = std::string(srcfiles[file_index - 1]);
  2903. }
  2904. // Deallocate all strings!
  2905. for (int i = 0; i < file_count; ++i) {
  2906. dwarf_dealloc(dwarf, srcfiles[i], DW_DLA_STRING);
  2907. }
  2908. dwarf_dealloc(dwarf, srcfiles, DW_DLA_LIST);
  2909. }
  2910. }
  2911. return file;
  2912. }
  2913. Dwarf_Die find_die(dwarf_fileobject &fobj, Dwarf_Addr addr) {
  2914. // Let's get to work! First see if we have a debug_aranges section so
  2915. // we can speed up the search
  2916. Dwarf_Debug dwarf = fobj.dwarf_handle.get();
  2917. Dwarf_Error error = DW_DLE_NE;
  2918. Dwarf_Arange *aranges;
  2919. Dwarf_Signed arange_count;
  2920. Dwarf_Die returnDie;
  2921. bool found = false;
  2922. if (dwarf_get_aranges(dwarf, &aranges, &arange_count, &error) !=
  2923. DW_DLV_OK) {
  2924. aranges = NULL;
  2925. }
  2926. if (aranges) {
  2927. // We have aranges. Get the one where our address is.
  2928. Dwarf_Arange arange;
  2929. if (dwarf_get_arange(aranges, arange_count, addr, &arange, &error) ==
  2930. DW_DLV_OK) {
  2931. // We found our address. Get the compilation-unit DIE offset
  2932. // represented by the given address range.
  2933. Dwarf_Off cu_die_offset;
  2934. if (dwarf_get_cu_die_offset(arange, &cu_die_offset, &error) ==
  2935. DW_DLV_OK) {
  2936. // Get the DIE at the offset returned by the aranges search.
  2937. // We set is_info to 1 to specify that the offset is from
  2938. // the .debug_info section (and not .debug_types)
  2939. int dwarf_result =
  2940. dwarf_offdie_b(dwarf, cu_die_offset, 1, &returnDie, &error);
  2941. found = dwarf_result == DW_DLV_OK;
  2942. }
  2943. dwarf_dealloc(dwarf, arange, DW_DLA_ARANGE);
  2944. }
  2945. }
  2946. if (found)
  2947. return returnDie; // The caller is responsible for freeing the die
  2948. // The search for aranges failed. Try to find our address by scanning
  2949. // all compilation units.
  2950. Dwarf_Unsigned next_cu_header;
  2951. Dwarf_Half tag = 0;
  2952. returnDie = 0;
  2953. while (!found &&
  2954. dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0,
  2955. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2956. if (returnDie)
  2957. dwarf_dealloc(dwarf, returnDie, DW_DLA_DIE);
  2958. if (dwarf_siblingof(dwarf, 0, &returnDie, &error) == DW_DLV_OK) {
  2959. if ((dwarf_tag(returnDie, &tag, &error) == DW_DLV_OK) &&
  2960. tag == DW_TAG_compile_unit) {
  2961. if (die_has_pc(fobj, returnDie, addr)) {
  2962. found = true;
  2963. }
  2964. }
  2965. }
  2966. }
  2967. if (found) {
  2968. while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0,
  2969. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2970. // Reset the cu header state. Libdwarf's next_cu_header API
  2971. // keeps its own iterator per Dwarf_Debug that can't be reset.
  2972. // We need to keep fetching elements until the end.
  2973. }
  2974. }
  2975. if (found)
  2976. return returnDie;
  2977. // We couldn't find any compilation units with ranges or a high/low pc.
  2978. // Try again by looking at all DIEs in all compilation units.
  2979. Dwarf_Die cudie;
  2980. while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0,
  2981. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2982. if (dwarf_siblingof(dwarf, 0, &cudie, &error) == DW_DLV_OK) {
  2983. Dwarf_Die die_mem = 0;
  2984. Dwarf_Die resultDie = find_fundie_by_pc(fobj, cudie, addr, die_mem);
  2985. if (resultDie) {
  2986. found = true;
  2987. break;
  2988. }
  2989. }
  2990. }
  2991. if (found) {
  2992. while (dwarf_next_cu_header_d(dwarf, 1, 0, 0, 0, 0, 0, 0, 0, 0,
  2993. &next_cu_header, 0, &error) == DW_DLV_OK) {
  2994. // Reset the cu header state. Libdwarf's next_cu_header API
  2995. // keeps its own iterator per Dwarf_Debug that can't be reset.
  2996. // We need to keep fetching elements until the end.
  2997. }
  2998. }
  2999. if (found)
  3000. return cudie;
  3001. // We failed.
  3002. return NULL;
  3003. }
  3004. };
  3005. #endif // BACKWARD_HAS_DWARF == 1
  3006. template <>
  3007. class TraceResolverImpl<system_tag::linux_tag>
  3008. : public TraceResolverLinuxImpl<trace_resolver_tag::current> {};
  3009. #endif // BACKWARD_SYSTEM_LINUX
  3010. #ifdef BACKWARD_SYSTEM_DARWIN
  3011. template <typename STACKTRACE_TAG> class TraceResolverDarwinImpl;
  3012. template <>
  3013. class TraceResolverDarwinImpl<trace_resolver_tag::backtrace_symbol>
  3014. : public TraceResolverImplBase {
  3015. public:
  3016. void load_addresses(void *const*addresses, int address_count) override {
  3017. if (address_count == 0) {
  3018. return;
  3019. }
  3020. _symbols.reset(backtrace_symbols(addresses, address_count));
  3021. }
  3022. ResolvedTrace resolve(ResolvedTrace trace) override {
  3023. // parse:
  3024. // <n> <file> <addr> <mangled-name> + <offset>
  3025. char *filename = _symbols[trace.idx];
  3026. // skip "<n> "
  3027. while (*filename && *filename != ' ')
  3028. filename++;
  3029. while (*filename == ' ')
  3030. filename++;
  3031. // find start of <mangled-name> from end (<file> may contain a space)
  3032. char *p = filename + strlen(filename) - 1;
  3033. // skip to start of " + <offset>"
  3034. while (p > filename && *p != ' ')
  3035. p--;
  3036. while (p > filename && *p == ' ')
  3037. p--;
  3038. while (p > filename && *p != ' ')
  3039. p--;
  3040. while (p > filename && *p == ' ')
  3041. p--;
  3042. char *funcname_end = p + 1;
  3043. // skip to start of "<manged-name>"
  3044. while (p > filename && *p != ' ')
  3045. p--;
  3046. char *funcname = p + 1;
  3047. // skip to start of " <addr> "
  3048. while (p > filename && *p == ' ')
  3049. p--;
  3050. while (p > filename && *p != ' ')
  3051. p--;
  3052. while (p > filename && *p == ' ')
  3053. p--;
  3054. // skip "<file>", handling the case where it contains a
  3055. char *filename_end = p + 1;
  3056. if (p == filename) {
  3057. // something went wrong, give up
  3058. filename_end = filename + strlen(filename);
  3059. funcname = filename_end;
  3060. }
  3061. trace.object_filename.assign(
  3062. filename, filename_end); // ok even if filename_end is the ending \0
  3063. // (then we assign entire string)
  3064. if (*funcname) { // if it's not end of string
  3065. *funcname_end = '\0';
  3066. trace.object_function = this->demangle(funcname);
  3067. trace.object_function += " ";
  3068. trace.object_function += (funcname_end + 1);
  3069. trace.source.function = trace.object_function; // we cannot do better.
  3070. }
  3071. return trace;
  3072. }
  3073. private:
  3074. details::handle<char **> _symbols;
  3075. };
  3076. template <>
  3077. class TraceResolverImpl<system_tag::darwin_tag>
  3078. : public TraceResolverDarwinImpl<trace_resolver_tag::current> {};
  3079. #endif // BACKWARD_SYSTEM_DARWIN
  3080. #ifdef BACKWARD_SYSTEM_WINDOWS
  3081. // Load all symbol info
  3082. // Based on:
  3083. // https://stackoverflow.com/questions/6205981/windows-c-stack-trace-from-a-running-app/28276227#28276227
  3084. struct module_data {
  3085. std::string image_name;
  3086. std::string module_name;
  3087. void *base_address;
  3088. DWORD load_size;
  3089. };
  3090. class get_mod_info {
  3091. HANDLE process;
  3092. static const int buffer_length = 4096;
  3093. public:
  3094. get_mod_info(HANDLE h) : process(h) {}
  3095. module_data operator()(HMODULE module) {
  3096. module_data ret;
  3097. char temp[buffer_length];
  3098. MODULEINFO mi;
  3099. GetModuleInformation(process, module, &mi, sizeof(mi));
  3100. ret.base_address = mi.lpBaseOfDll;
  3101. ret.load_size = mi.SizeOfImage;
  3102. GetModuleFileNameExA(process, module, temp, sizeof(temp));
  3103. ret.image_name = temp;
  3104. GetModuleBaseNameA(process, module, temp, sizeof(temp));
  3105. ret.module_name = temp;
  3106. std::vector<char> img(ret.image_name.begin(), ret.image_name.end());
  3107. std::vector<char> mod(ret.module_name.begin(), ret.module_name.end());
  3108. SymLoadModule64(process, 0, &img[0], &mod[0], (DWORD64)ret.base_address,
  3109. ret.load_size);
  3110. return ret;
  3111. }
  3112. };
  3113. template <> class TraceResolverImpl<system_tag::windows_tag>
  3114. : public TraceResolverImplBase {
  3115. public:
  3116. TraceResolverImpl() {
  3117. HANDLE process = GetCurrentProcess();
  3118. std::vector<module_data> modules;
  3119. DWORD cbNeeded;
  3120. std::vector<HMODULE> module_handles(1);
  3121. SymInitialize(process, NULL, false);
  3122. DWORD symOptions = SymGetOptions();
  3123. symOptions |= SYMOPT_LOAD_LINES | SYMOPT_UNDNAME;
  3124. SymSetOptions(symOptions);
  3125. EnumProcessModules(process, &module_handles[0],
  3126. module_handles.size() * sizeof(HMODULE), &cbNeeded);
  3127. module_handles.resize(cbNeeded / sizeof(HMODULE));
  3128. EnumProcessModules(process, &module_handles[0],
  3129. module_handles.size() * sizeof(HMODULE), &cbNeeded);
  3130. std::transform(module_handles.begin(), module_handles.end(),
  3131. std::back_inserter(modules), get_mod_info(process));
  3132. void *base = modules[0].base_address;
  3133. IMAGE_NT_HEADERS *h = ImageNtHeader(base);
  3134. image_type = h->FileHeader.Machine;
  3135. }
  3136. static const int max_sym_len = 255;
  3137. struct symbol_t {
  3138. SYMBOL_INFO sym;
  3139. char buffer[max_sym_len];
  3140. } sym;
  3141. DWORD64 displacement;
  3142. ResolvedTrace resolve(ResolvedTrace t) override {
  3143. HANDLE process = GetCurrentProcess();
  3144. char name[256];
  3145. memset(&sym, 0, sizeof(sym));
  3146. sym.sym.SizeOfStruct = sizeof(SYMBOL_INFO);
  3147. sym.sym.MaxNameLen = max_sym_len;
  3148. if (!SymFromAddr(process, (ULONG64)t.addr, &displacement, &sym.sym)) {
  3149. // TODO: error handling everywhere
  3150. char* lpMsgBuf;
  3151. DWORD dw = GetLastError();
  3152. if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  3153. FORMAT_MESSAGE_FROM_SYSTEM |
  3154. FORMAT_MESSAGE_IGNORE_INSERTS,
  3155. NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  3156. (char*)&lpMsgBuf, 0, NULL)) {
  3157. std::fprintf(stderr, "%s\n", lpMsgBuf);
  3158. LocalFree(lpMsgBuf);
  3159. }
  3160. // abort();
  3161. }
  3162. UnDecorateSymbolName(sym.sym.Name, (PSTR)name, 256, UNDNAME_COMPLETE);
  3163. DWORD offset = 0;
  3164. IMAGEHLP_LINE line;
  3165. if (SymGetLineFromAddr(process, (ULONG64)t.addr, &offset, &line)) {
  3166. t.object_filename = line.FileName;
  3167. t.source.filename = line.FileName;
  3168. t.source.line = line.LineNumber;
  3169. t.source.col = offset;
  3170. }
  3171. t.source.function = name;
  3172. t.object_filename = "";
  3173. t.object_function = name;
  3174. return t;
  3175. }
  3176. DWORD machine_type() const { return image_type; }
  3177. private:
  3178. DWORD image_type;
  3179. };
  3180. #endif
  3181. class TraceResolver : public TraceResolverImpl<system_tag::current_tag> {};
  3182. /*************** CODE SNIPPET ***************/
  3183. class SourceFile {
  3184. public:
  3185. typedef std::vector<std::pair<unsigned, std::string>> lines_t;
  3186. SourceFile() {}
  3187. SourceFile(const std::string &path) {
  3188. // 1. If BACKWARD_CXX_SOURCE_PREFIXES is set then assume it contains
  3189. // a colon-separated list of path prefixes. Try prepending each
  3190. // to the given path until a valid file is found.
  3191. const std::vector<std::string> &prefixes = get_paths_from_env_variable();
  3192. for (size_t i = 0; i < prefixes.size(); ++i) {
  3193. // Double slashes (//) should not be a problem.
  3194. std::string new_path = prefixes[i] + '/' + path;
  3195. _file.reset(new std::ifstream(new_path.c_str()));
  3196. if (is_open())
  3197. break;
  3198. }
  3199. // 2. If no valid file found then fallback to opening the path as-is.
  3200. if (!_file || !is_open()) {
  3201. _file.reset(new std::ifstream(path.c_str()));
  3202. }
  3203. }
  3204. bool is_open() const { return _file->is_open(); }
  3205. lines_t &get_lines(unsigned line_start, unsigned line_count, lines_t &lines) {
  3206. using namespace std;
  3207. // This function make uses of the dumbest algo ever:
  3208. // 1) seek(0)
  3209. // 2) read lines one by one and discard until line_start
  3210. // 3) read line one by one until line_start + line_count
  3211. //
  3212. // If you are getting snippets many time from the same file, it is
  3213. // somewhat a waste of CPU, feel free to benchmark and propose a
  3214. // better solution ;)
  3215. _file->clear();
  3216. _file->seekg(0);
  3217. string line;
  3218. unsigned line_idx;
  3219. for (line_idx = 1; line_idx < line_start; ++line_idx) {
  3220. std::getline(*_file, line);
  3221. if (!*_file) {
  3222. return lines;
  3223. }
  3224. }
  3225. // think of it like a lambda in C++98 ;)
  3226. // but look, I will reuse it two times!
  3227. // What a good boy am I.
  3228. struct isspace {
  3229. bool operator()(char c) { return std::isspace(c); }
  3230. };
  3231. bool started = false;
  3232. for (; line_idx < line_start + line_count; ++line_idx) {
  3233. getline(*_file, line);
  3234. if (!*_file) {
  3235. return lines;
  3236. }
  3237. if (!started) {
  3238. if (std::find_if(line.begin(), line.end(), not_isspace()) == line.end())
  3239. continue;
  3240. started = true;
  3241. }
  3242. lines.push_back(make_pair(line_idx, line));
  3243. }
  3244. lines.erase(
  3245. std::find_if(lines.rbegin(), lines.rend(), not_isempty()).base(),
  3246. lines.end());
  3247. return lines;
  3248. }
  3249. lines_t get_lines(unsigned line_start, unsigned line_count) {
  3250. lines_t lines;
  3251. return get_lines(line_start, line_count, lines);
  3252. }
  3253. // there is no find_if_not in C++98, lets do something crappy to
  3254. // workaround.
  3255. struct not_isspace {
  3256. bool operator()(char c) { return !std::isspace(c); }
  3257. };
  3258. // and define this one here because C++98 is not happy with local defined
  3259. // struct passed to template functions, fuuuu.
  3260. struct not_isempty {
  3261. bool operator()(const lines_t::value_type &p) {
  3262. return !(std::find_if(p.second.begin(), p.second.end(), not_isspace()) ==
  3263. p.second.end());
  3264. }
  3265. };
  3266. void swap(SourceFile &b) { _file.swap(b._file); }
  3267. #ifdef BACKWARD_ATLEAST_CXX11
  3268. SourceFile(SourceFile &&from) : _file(nullptr) { swap(from); }
  3269. SourceFile &operator=(SourceFile &&from) {
  3270. swap(from);
  3271. return *this;
  3272. }
  3273. #else
  3274. explicit SourceFile(const SourceFile &from) {
  3275. // some sort of poor man's move semantic.
  3276. swap(const_cast<SourceFile &>(from));
  3277. }
  3278. SourceFile &operator=(const SourceFile &from) {
  3279. // some sort of poor man's move semantic.
  3280. swap(const_cast<SourceFile &>(from));
  3281. return *this;
  3282. }
  3283. #endif
  3284. private:
  3285. details::handle<std::ifstream *, details::default_delete<std::ifstream *>>
  3286. _file;
  3287. std::vector<std::string> get_paths_from_env_variable_impl() {
  3288. std::vector<std::string> paths;
  3289. const char *prefixes_str = std::getenv("BACKWARD_CXX_SOURCE_PREFIXES");
  3290. if (prefixes_str && prefixes_str[0]) {
  3291. paths = details::split_source_prefixes(prefixes_str);
  3292. }
  3293. return paths;
  3294. }
  3295. const std::vector<std::string> &get_paths_from_env_variable() {
  3296. static std::vector<std::string> paths = get_paths_from_env_variable_impl();
  3297. return paths;
  3298. }
  3299. #ifdef BACKWARD_ATLEAST_CXX11
  3300. SourceFile(const SourceFile &) = delete;
  3301. SourceFile &operator=(const SourceFile &) = delete;
  3302. #endif
  3303. };
  3304. class SnippetFactory {
  3305. public:
  3306. typedef SourceFile::lines_t lines_t;
  3307. lines_t get_snippet(const std::string &filename, unsigned line_start,
  3308. unsigned context_size) {
  3309. SourceFile &src_file = get_src_file(filename);
  3310. unsigned start = line_start - context_size / 2;
  3311. return src_file.get_lines(start, context_size);
  3312. }
  3313. lines_t get_combined_snippet(const std::string &filename_a, unsigned line_a,
  3314. const std::string &filename_b, unsigned line_b,
  3315. unsigned context_size) {
  3316. SourceFile &src_file_a = get_src_file(filename_a);
  3317. SourceFile &src_file_b = get_src_file(filename_b);
  3318. lines_t lines =
  3319. src_file_a.get_lines(line_a - context_size / 4, context_size / 2);
  3320. src_file_b.get_lines(line_b - context_size / 4, context_size / 2, lines);
  3321. return lines;
  3322. }
  3323. lines_t get_coalesced_snippet(const std::string &filename, unsigned line_a,
  3324. unsigned line_b, unsigned context_size) {
  3325. SourceFile &src_file = get_src_file(filename);
  3326. using std::max;
  3327. using std::min;
  3328. unsigned a = min(line_a, line_b);
  3329. unsigned b = max(line_a, line_b);
  3330. if ((b - a) < (context_size / 3)) {
  3331. return src_file.get_lines((a + b - context_size + 1) / 2, context_size);
  3332. }
  3333. lines_t lines = src_file.get_lines(a - context_size / 4, context_size / 2);
  3334. src_file.get_lines(b - context_size / 4, context_size / 2, lines);
  3335. return lines;
  3336. }
  3337. private:
  3338. typedef details::hashtable<std::string, SourceFile>::type src_files_t;
  3339. src_files_t _src_files;
  3340. SourceFile &get_src_file(const std::string &filename) {
  3341. src_files_t::iterator it = _src_files.find(filename);
  3342. if (it != _src_files.end()) {
  3343. return it->second;
  3344. }
  3345. SourceFile &new_src_file = _src_files[filename];
  3346. new_src_file = SourceFile(filename);
  3347. return new_src_file;
  3348. }
  3349. };
  3350. /*************** PRINTER ***************/
  3351. namespace ColorMode {
  3352. enum type { automatic, never, always };
  3353. }
  3354. class cfile_streambuf : public std::streambuf {
  3355. public:
  3356. cfile_streambuf(FILE *_sink) : sink(_sink) {}
  3357. int_type underflow() override { return traits_type::eof(); }
  3358. int_type overflow(int_type ch) override {
  3359. if (traits_type::not_eof(ch) && fputc(ch, sink) != EOF) {
  3360. return ch;
  3361. }
  3362. return traits_type::eof();
  3363. }
  3364. std::streamsize xsputn(const char_type *s, std::streamsize count) override {
  3365. return static_cast<std::streamsize>(
  3366. fwrite(s, sizeof *s, static_cast<size_t>(count), sink));
  3367. }
  3368. #ifdef BACKWARD_ATLEAST_CXX11
  3369. public:
  3370. cfile_streambuf(const cfile_streambuf &) = delete;
  3371. cfile_streambuf &operator=(const cfile_streambuf &) = delete;
  3372. #else
  3373. private:
  3374. cfile_streambuf(const cfile_streambuf &);
  3375. cfile_streambuf &operator=(const cfile_streambuf &);
  3376. #endif
  3377. private:
  3378. FILE *sink;
  3379. std::vector<char> buffer;
  3380. };
  3381. #ifdef BACKWARD_SYSTEM_LINUX
  3382. namespace Color {
  3383. enum type { yellow = 33, purple = 35, reset = 39 };
  3384. } // namespace Color
  3385. class Colorize {
  3386. public:
  3387. Colorize(std::ostream &os) : _os(os), _reset(false), _enabled(false) {}
  3388. void activate(ColorMode::type mode) { _enabled = mode == ColorMode::always; }
  3389. void activate(ColorMode::type mode, FILE *fp) { activate(mode, fileno(fp)); }
  3390. void set_color(Color::type ccode) {
  3391. if (!_enabled)
  3392. return;
  3393. // I assume that the terminal can handle basic colors. Seriously I
  3394. // don't want to deal with all the termcap shit.
  3395. _os << "\033[" << static_cast<int>(ccode) << "m";
  3396. _reset = (ccode != Color::reset);
  3397. }
  3398. ~Colorize() {
  3399. if (_reset) {
  3400. set_color(Color::reset);
  3401. }
  3402. }
  3403. private:
  3404. void activate(ColorMode::type mode, int fd) {
  3405. activate(mode == ColorMode::automatic && isatty(fd) ? ColorMode::always
  3406. : mode);
  3407. }
  3408. std::ostream &_os;
  3409. bool _reset;
  3410. bool _enabled;
  3411. };
  3412. #else // ndef BACKWARD_SYSTEM_LINUX
  3413. namespace Color {
  3414. enum type { yellow = 0, purple = 0, reset = 0 };
  3415. } // namespace Color
  3416. class Colorize {
  3417. public:
  3418. Colorize(std::ostream &) {}
  3419. void activate(ColorMode::type) {}
  3420. void activate(ColorMode::type, FILE *) {}
  3421. void set_color(Color::type) {}
  3422. };
  3423. #endif // BACKWARD_SYSTEM_LINUX
  3424. class Printer {
  3425. public:
  3426. bool snippet;
  3427. ColorMode::type color_mode;
  3428. bool address;
  3429. bool object;
  3430. int inliner_context_size;
  3431. int trace_context_size;
  3432. Printer()
  3433. : snippet(true), color_mode(ColorMode::automatic), address(false),
  3434. object(false), inliner_context_size(5), trace_context_size(7) {}
  3435. template <typename ST> FILE *print(ST &st, FILE *fp = stderr) {
  3436. cfile_streambuf obuf(fp);
  3437. std::ostream os(&obuf);
  3438. Colorize colorize(os);
  3439. colorize.activate(color_mode, fp);
  3440. print_stacktrace(st, os, colorize);
  3441. return fp;
  3442. }
  3443. template <typename ST> std::ostream &print(ST &st, std::ostream &os) {
  3444. Colorize colorize(os);
  3445. colorize.activate(color_mode);
  3446. print_stacktrace(st, os, colorize);
  3447. return os;
  3448. }
  3449. template <typename IT>
  3450. FILE *print(IT begin, IT end, FILE *fp = stderr, size_t thread_id = 0) {
  3451. cfile_streambuf obuf(fp);
  3452. std::ostream os(&obuf);
  3453. Colorize colorize(os);
  3454. colorize.activate(color_mode, fp);
  3455. print_stacktrace(begin, end, os, thread_id, colorize);
  3456. return fp;
  3457. }
  3458. template <typename IT>
  3459. std::ostream &print(IT begin, IT end, std::ostream &os,
  3460. size_t thread_id = 0) {
  3461. Colorize colorize(os);
  3462. colorize.activate(color_mode);
  3463. print_stacktrace(begin, end, os, thread_id, colorize);
  3464. return os;
  3465. }
  3466. TraceResolver const &resolver() const { return _resolver; }
  3467. private:
  3468. TraceResolver _resolver;
  3469. SnippetFactory _snippets;
  3470. template <typename ST>
  3471. void print_stacktrace(ST &st, std::ostream &os, Colorize &colorize) {
  3472. print_header(os, st.thread_id());
  3473. _resolver.load_stacktrace(st);
  3474. for (size_t trace_idx = st.size(); trace_idx > 0; --trace_idx) {
  3475. print_trace(os, _resolver.resolve(st[trace_idx - 1]), colorize);
  3476. }
  3477. }
  3478. template <typename IT>
  3479. void print_stacktrace(IT begin, IT end, std::ostream &os, size_t thread_id,
  3480. Colorize &colorize) {
  3481. print_header(os, thread_id);
  3482. for (; begin != end; ++begin) {
  3483. print_trace(os, *begin, colorize);
  3484. }
  3485. }
  3486. void print_header(std::ostream &os, size_t thread_id) {
  3487. os << "Stack trace (most recent call last)";
  3488. if (thread_id) {
  3489. os << " in thread " << thread_id;
  3490. }
  3491. os << ":\n";
  3492. }
  3493. void print_trace(std::ostream &os, const ResolvedTrace &trace,
  3494. Colorize &colorize) {
  3495. os << "#" << std::left << std::setw(2) << trace.idx << std::right;
  3496. bool already_indented = true;
  3497. if (!trace.source.filename.size() || object) {
  3498. os << " Object \"" << trace.object_filename << "\", at " << trace.addr
  3499. << ", in " << trace.object_function << "\n";
  3500. already_indented = false;
  3501. }
  3502. for (size_t inliner_idx = trace.inliners.size(); inliner_idx > 0;
  3503. --inliner_idx) {
  3504. if (!already_indented) {
  3505. os << " ";
  3506. }
  3507. const ResolvedTrace::SourceLoc &inliner_loc =
  3508. trace.inliners[inliner_idx - 1];
  3509. print_source_loc(os, " | ", inliner_loc);
  3510. if (snippet) {
  3511. print_snippet(os, " | ", inliner_loc, colorize, Color::purple,
  3512. inliner_context_size);
  3513. }
  3514. already_indented = false;
  3515. }
  3516. if (trace.source.filename.size()) {
  3517. if (!already_indented) {
  3518. os << " ";
  3519. }
  3520. print_source_loc(os, " ", trace.source, trace.addr);
  3521. if (snippet) {
  3522. print_snippet(os, " ", trace.source, colorize, Color::yellow,
  3523. trace_context_size);
  3524. }
  3525. }
  3526. }
  3527. void print_snippet(std::ostream &os, const char *indent,
  3528. const ResolvedTrace::SourceLoc &source_loc,
  3529. Colorize &colorize, Color::type color_code,
  3530. int context_size) {
  3531. using namespace std;
  3532. typedef SnippetFactory::lines_t lines_t;
  3533. lines_t lines = _snippets.get_snippet(source_loc.filename, source_loc.line,
  3534. static_cast<unsigned>(context_size));
  3535. for (lines_t::const_iterator it = lines.begin(); it != lines.end(); ++it) {
  3536. if (it->first == source_loc.line) {
  3537. colorize.set_color(color_code);
  3538. os << indent << ">";
  3539. } else {
  3540. os << indent << " ";
  3541. }
  3542. os << std::setw(4) << it->first << ": " << it->second << "\n";
  3543. if (it->first == source_loc.line) {
  3544. colorize.set_color(Color::reset);
  3545. }
  3546. }
  3547. }
  3548. void print_source_loc(std::ostream &os, const char *indent,
  3549. const ResolvedTrace::SourceLoc &source_loc,
  3550. void *addr = nullptr) {
  3551. os << indent << "Source \"" << source_loc.filename << "\", line "
  3552. << source_loc.line << ", in " << source_loc.function;
  3553. if (address && addr != nullptr) {
  3554. os << " [" << addr << "]";
  3555. }
  3556. os << "\n";
  3557. }
  3558. };
  3559. /*************** SIGNALS HANDLING ***************/
  3560. #if defined(BACKWARD_SYSTEM_LINUX) || defined(BACKWARD_SYSTEM_DARWIN)
  3561. class SignalHandling {
  3562. public:
  3563. static std::vector<int> make_default_signals() {
  3564. const int posix_signals[] = {
  3565. // Signals for which the default action is "Core".
  3566. SIGABRT, // Abort signal from abort(3)
  3567. SIGBUS, // Bus error (bad memory access)
  3568. SIGFPE, // Floating point exception
  3569. SIGILL, // Illegal Instruction
  3570. SIGIOT, // IOT trap. A synonym for SIGABRT
  3571. SIGQUIT, // Quit from keyboard
  3572. SIGSEGV, // Invalid memory reference
  3573. SIGSYS, // Bad argument to routine (SVr4)
  3574. SIGTRAP, // Trace/breakpoint trap
  3575. SIGXCPU, // CPU time limit exceeded (4.2BSD)
  3576. SIGXFSZ, // File size limit exceeded (4.2BSD)
  3577. #if defined(BACKWARD_SYSTEM_DARWIN)
  3578. SIGEMT, // emulation instruction executed
  3579. #endif
  3580. };
  3581. return std::vector<int>(posix_signals,
  3582. posix_signals +
  3583. sizeof posix_signals / sizeof posix_signals[0]);
  3584. }
  3585. SignalHandling(const std::vector<int> &posix_signals = make_default_signals())
  3586. : _loaded(false) {
  3587. bool success = true;
  3588. const size_t stack_size = 1024 * 1024 * 8;
  3589. _stack_content.reset(static_cast<char *>(malloc(stack_size)));
  3590. if (_stack_content) {
  3591. stack_t ss;
  3592. ss.ss_sp = _stack_content.get();
  3593. ss.ss_size = stack_size;
  3594. ss.ss_flags = 0;
  3595. if (sigaltstack(&ss, nullptr) < 0) {
  3596. success = false;
  3597. }
  3598. } else {
  3599. success = false;
  3600. }
  3601. for (size_t i = 0; i < posix_signals.size(); ++i) {
  3602. struct sigaction action;
  3603. memset(&action, 0, sizeof action);
  3604. action.sa_flags =
  3605. static_cast<int>(SA_SIGINFO | SA_ONSTACK | SA_NODEFER | SA_RESETHAND);
  3606. sigfillset(&action.sa_mask);
  3607. sigdelset(&action.sa_mask, posix_signals[i]);
  3608. #if defined(__clang__)
  3609. #pragma clang diagnostic push
  3610. #pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
  3611. #endif
  3612. action.sa_sigaction = &sig_handler;
  3613. #if defined(__clang__)
  3614. #pragma clang diagnostic pop
  3615. #endif
  3616. int r = sigaction(posix_signals[i], &action, nullptr);
  3617. if (r < 0)
  3618. success = false;
  3619. }
  3620. _loaded = success;
  3621. }
  3622. bool loaded() const { return _loaded; }
  3623. static void handleSignal(int, siginfo_t *info, void *_ctx) {
  3624. ucontext_t *uctx = static_cast<ucontext_t *>(_ctx);
  3625. StackTrace st;
  3626. void *error_addr = nullptr;
  3627. #ifdef REG_RIP // x86_64
  3628. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_RIP]);
  3629. #elif defined(REG_EIP) // x86_32
  3630. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_EIP]);
  3631. #elif defined(__arm__)
  3632. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.arm_pc);
  3633. #elif defined(__aarch64__)
  3634. #if defined(__APPLE__)
  3635. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__pc);
  3636. #else
  3637. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.pc);
  3638. #endif
  3639. #elif defined(__loongarch__)
  3640. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.__pc);
  3641. #elif defined(__mips__)
  3642. error_addr = reinterpret_cast<void *>(
  3643. reinterpret_cast<struct sigcontext *>(&uctx->uc_mcontext)->sc_pc);
  3644. #elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) || \
  3645. defined(__POWERPC__)
  3646. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.regs->nip);
  3647. #elif defined(__riscv)
  3648. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.__gregs[REG_PC]);
  3649. #elif defined(__s390x__)
  3650. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.psw.addr);
  3651. #elif defined(__APPLE__) && defined(__x86_64__)
  3652. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__rip);
  3653. #elif defined(__APPLE__)
  3654. error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__eip);
  3655. #else
  3656. #warning ":/ sorry, ain't know no nothing none not of your architecture!"
  3657. #endif
  3658. if (error_addr) {
  3659. st.load_from(error_addr, 32, reinterpret_cast<void *>(uctx),
  3660. info->si_addr);
  3661. } else {
  3662. st.load_here(32, reinterpret_cast<void *>(uctx), info->si_addr);
  3663. }
  3664. Printer printer;
  3665. printer.address = true;
  3666. printer.print(st, stderr);
  3667. #if _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
  3668. psiginfo(info, nullptr);
  3669. #else
  3670. (void)info;
  3671. #endif
  3672. }
  3673. private:
  3674. details::handle<char *> _stack_content;
  3675. bool _loaded;
  3676. #ifdef __GNUC__
  3677. __attribute__((noreturn))
  3678. #endif
  3679. static void
  3680. sig_handler(int signo, siginfo_t *info, void *_ctx) {
  3681. handleSignal(signo, info, _ctx);
  3682. // try to forward the signal.
  3683. raise(info->si_signo);
  3684. // terminate the process immediately.
  3685. puts("watf? exit");
  3686. _exit(EXIT_FAILURE);
  3687. }
  3688. };
  3689. #endif // BACKWARD_SYSTEM_LINUX || BACKWARD_SYSTEM_DARWIN
  3690. #ifdef BACKWARD_SYSTEM_WINDOWS
  3691. class SignalHandling {
  3692. public:
  3693. SignalHandling(const std::vector<int> & = std::vector<int>())
  3694. : reporter_thread_([]() {
  3695. /* We handle crashes in a utility thread:
  3696. backward structures and some Windows functions called here
  3697. need stack space, which we do not have when we encounter a
  3698. stack overflow.
  3699. To support reporting stack traces during a stack overflow,
  3700. we create a utility thread at startup, which waits until a
  3701. crash happens or the program exits normally. */
  3702. {
  3703. std::unique_lock<std::mutex> lk(mtx());
  3704. cv().wait(lk, [] { return crashed() != crash_status::running; });
  3705. }
  3706. if (crashed() == crash_status::crashed) {
  3707. handle_stacktrace(skip_recs());
  3708. }
  3709. {
  3710. std::unique_lock<std::mutex> lk(mtx());
  3711. crashed() = crash_status::ending;
  3712. }
  3713. cv().notify_one();
  3714. }) {
  3715. SetUnhandledExceptionFilter(crash_handler);
  3716. signal(SIGABRT, signal_handler);
  3717. _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
  3718. std::set_terminate(&terminator);
  3719. #ifndef BACKWARD_ATLEAST_CXX17
  3720. std::set_unexpected(&terminator);
  3721. #endif
  3722. _set_purecall_handler(&terminator);
  3723. _set_invalid_parameter_handler(&invalid_parameter_handler);
  3724. }
  3725. bool loaded() const { return true; }
  3726. ~SignalHandling() {
  3727. {
  3728. std::unique_lock<std::mutex> lk(mtx());
  3729. crashed() = crash_status::normal_exit;
  3730. }
  3731. cv().notify_one();
  3732. reporter_thread_.join();
  3733. }
  3734. private:
  3735. static CONTEXT *ctx() {
  3736. static CONTEXT data;
  3737. return &data;
  3738. }
  3739. enum class crash_status { running, crashed, normal_exit, ending };
  3740. static crash_status &crashed() {
  3741. static crash_status data;
  3742. return data;
  3743. }
  3744. static std::mutex &mtx() {
  3745. static std::mutex data;
  3746. return data;
  3747. }
  3748. static std::condition_variable &cv() {
  3749. static std::condition_variable data;
  3750. return data;
  3751. }
  3752. static HANDLE &thread_handle() {
  3753. static HANDLE handle;
  3754. return handle;
  3755. }
  3756. std::thread reporter_thread_;
  3757. // TODO: how not to hardcode these?
  3758. static const constexpr int signal_skip_recs =
  3759. #ifdef __clang__
  3760. // With clang, RtlCaptureContext also captures the stack frame of the
  3761. // current function Below that, there ar 3 internal Windows functions
  3762. 4
  3763. #else
  3764. // With MSVC cl, RtlCaptureContext misses the stack frame of the current
  3765. // function The first entries during StackWalk are the 3 internal Windows
  3766. // functions
  3767. 3
  3768. #endif
  3769. ;
  3770. static int &skip_recs() {
  3771. static int data;
  3772. return data;
  3773. }
  3774. static inline void terminator() {
  3775. crash_handler(signal_skip_recs);
  3776. abort();
  3777. }
  3778. static inline void signal_handler(int) {
  3779. crash_handler(signal_skip_recs);
  3780. abort();
  3781. }
  3782. static inline void __cdecl invalid_parameter_handler(const wchar_t *,
  3783. const wchar_t *,
  3784. const wchar_t *,
  3785. unsigned int,
  3786. uintptr_t) {
  3787. crash_handler(signal_skip_recs);
  3788. abort();
  3789. }
  3790. NOINLINE static LONG WINAPI crash_handler(EXCEPTION_POINTERS *info) {
  3791. // The exception info supplies a trace from exactly where the issue was,
  3792. // no need to skip records
  3793. crash_handler(0, info->ContextRecord);
  3794. return EXCEPTION_CONTINUE_SEARCH;
  3795. }
  3796. NOINLINE static void crash_handler(int skip, CONTEXT *ct = nullptr) {
  3797. if (ct == nullptr) {
  3798. RtlCaptureContext(ctx());
  3799. } else {
  3800. memcpy(ctx(), ct, sizeof(CONTEXT));
  3801. }
  3802. DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
  3803. GetCurrentProcess(), &thread_handle(), 0, FALSE,
  3804. DUPLICATE_SAME_ACCESS);
  3805. skip_recs() = skip;
  3806. {
  3807. std::unique_lock<std::mutex> lk(mtx());
  3808. crashed() = crash_status::crashed;
  3809. }
  3810. cv().notify_one();
  3811. {
  3812. std::unique_lock<std::mutex> lk(mtx());
  3813. cv().wait(lk, [] { return crashed() != crash_status::crashed; });
  3814. }
  3815. }
  3816. static void handle_stacktrace(int skip_frames = 0) {
  3817. // printer creates the TraceResolver, which can supply us a machine type
  3818. // for stack walking. Without this, StackTrace can only guess using some
  3819. // macros.
  3820. // StackTrace also requires that the PDBs are already loaded, which is done
  3821. // in the constructor of TraceResolver
  3822. Printer printer;
  3823. StackTrace st;
  3824. st.set_machine_type(printer.resolver().machine_type());
  3825. st.set_thread_handle(thread_handle());
  3826. st.load_here(32 + skip_frames, ctx());
  3827. st.skip_n_firsts(skip_frames);
  3828. printer.address = true;
  3829. printer.print(st, std::cerr);
  3830. }
  3831. };
  3832. #endif // BACKWARD_SYSTEM_WINDOWS
  3833. #ifdef BACKWARD_SYSTEM_UNKNOWN
  3834. class SignalHandling {
  3835. public:
  3836. SignalHandling(const std::vector<int> & = std::vector<int>()) {}
  3837. bool init() { return false; }
  3838. bool loaded() { return false; }
  3839. };
  3840. #endif // BACKWARD_SYSTEM_UNKNOWN
  3841. } // namespace backward
  3842. #endif /* H_GUARD */