[INACTIVE] Avian is a lightweight virtual machine and class library designed to provide a useful subset of Java's features, suitable for building self-contained applications.
I'm hitting a null pointer crash in Avian, somewhere in the guts of handling an invokedynamic instruction. This is with avian in "compile mode". It doesn't matter if Avian is compiled with the JDK image/source or with Avian's classpath.
This was compiled and run on x64 Ubuntu 16.04.5 LTS and another Linux-based ARM platform.
From that we can see that dynamicTable was set by the rest of the code in addDynamic for the t->m->processor, but this doesn't appear to have been copied over to the t->dynamicTable field? I think it might be a simple case of a missing call to updateDynamicTable(t, t); or something like that?? That might be understating the problem, however.
That app is the smallest I can make it, though smaller examples might exist. Changing practically anything in this example app makes the problem disappear. (Infact using that information I've managed to make my original app not crash by working around the issue and accessing a class earlier than it normally would. This seems to "fix" the problem for me, though the underlying issue is obviously still present.)
I'm hitting a null pointer crash in Avian, somewhere in the guts of handling an
invokedynamic
instruction. This is with avian in "compile mode". It doesn't matter if Avian is compiled with the JDK image/source or with Avian's classpath.This was compiled and run on x64 Ubuntu 16.04.5 LTS and another Linux-based ARM platform.
The crash details from debugger:
CLICK ME: Backtrace from lldb
```text Process 14395 stopped * thread #3: tid = 14399, 0x00007ffff7af5564 libjvm.so`(anonymous namespace)::local::addDynamic(t=0x0000555555971c58, invocation=0x00007fffe401e758)::local::MyThread *, vm::GcInvocation *) + 1482 at compile.cpp:1373, name = 'avian-dynamic', stop reason = signal SIGSEGV: invalid address (fault address: 0x8) frame #0: 0x00007ffff7af5564 libjvm.so`(anonymous namespace)::local::addDynamic(t=0x0000555555971c58, invocation=0x00007fffe401e758)::local::MyThread *, vm::GcInvocation *) + 1482 at compile.cpp:1373 1370 compileRoots(t)->dynamicThunks()->body()[index * 2] = thunk; 1371 compileRoots(t)->dynamicThunks()->body()[(index * 2) + 1] = size; 1372 -> 1373 t->dynamicTable[index] = reinterpret_castProbing some variables a bit further:
CLICK ME: print of the Thread variable in debugger
```text (lldb) frame variable *t error: libjvm.so 0x000002a5: DW_TAG_member '__size' refers to type 0x000002bc which extends beyond the bounds of 0x00000221 error: libjvm.so 0x00000357: DW_TAG_member '__size' refers to type 0x00000375 which extends beyond the bounds of 0x000002d7 ((anonymous namespace)::local::MyThread) *t = { vm::Thread = { vtable = 0x000055555575d9f8 m = 0x000055555575d898 parent = 0x00005555557628d8 peer = 0x00005555558d0558 child = 0x0000000000000000 waitNext = 0x0000000000000000 state = ActiveState criticalLevel = 0 systemThread = 0x0000555555972630 lock = 0x00005555559725d0 javaThread = 0x0000555555897460 exception = 0x0000000000000000 heapIndex = 7303 heapOffset = 8190 protector = 0x00007ffff0de8ce0 classInitStack = 0x00007ffff0de9480 libraryLoadStack = 0x0000000000000000 resource = 0x00007ffff0de8640 checkpoint = 0x00007ffff0de99f0 runnable = { t = 0x0000555555971c58 } defaultHeap = 0x0000555555a91cd8 heap = 0x00007fffe4011968 backupHeap = { [0] = 0 [1] = 0 [2] = 0 [3] = 0 [4] = 0 [5] = 0 [6] = 0 [7] = 0 [8] = 0 [9] = 0 [10] = 0 [11] = 0 [12] = 0 [13] = 0 [14] = 0 [15] = 0 [16] = 0 [17] = 0 [18] = 0 [19] = 0 [20] = 0 [21] = 0 [22] = 0 [23] = 0 [24] = 0 [25] = 0 [26] = 0 [27] = 0 [28] = 0 [29] = 0 [30] = 0 [31] = 0 [32] = 0 [33] = 0 [34] = 0 [35] = 0 [36] = 0 [37] = 0 [38] = 0 [39] = 0 [40] = 0 [41] = 0 [42] = 0 [43] = 0 [44] = 0 [45] = 0 [46] = 0 [47] = 0 [48] = 0 [49] = 0 [50] = 0 [51] = 0 [52] = 0 [53] = 0 [54] = 0 [55] = 0 [56] = 0 [57] = 0 [58] = 0 [59] = 0 [60] = 0 [61] = 0 [62] = 0 [63] = 0 [64] = 0 [65] = 0 [66] = 0 [67] = 0 [68] = 0 [69] = 0 [70] = 0 [71] = 0 [72] = 0 [73] = 0 [74] = 0 [75] = 0 [76] = 0 [77] = 0 [78] = 0 [79] = 0 [80] = 0 [81] = 0 [82] = 0 [83] = 0 [84] = 0 [85] = 0 [86] = 0 [87] = 0 [88] = 0 [89] = 0 [90] = 0 [91] = 0 [92] = 0 [93] = 0 [94] = 0 [95] = 0 [96] = 0 [97] = 0 [98] = 0 [99] = 0 [100] = 0 [101] = 0 [102] = 0 [103] = 0 [104] = 0 [105] = 0 [106] = 0 [107] = 0 [108] = 0 [109] = 0 [110] = 0 [111] = 0 [112] = 0 [113] = 0 [114] = 0 [115] = 0 [116] = 0 [117] = 0 [118] = 0 [119] = 0 [120] = 0 [121] = 0 [122] = 0 [123] = 0 [124] = 0 [125] = 0 [126] = 0 [127] = 0 [128] = 0 [129] = 0 [130] = 0 [131] = 0 [132] = 0 [133] = 0 [134] = 0 [135] = 0 [136] = 0 [137] = 0 [138] = 0 [139] = 0 [140] = 0 [141] = 0 [142] = 0 [143] = 0 [144] = 0 [145] = 0 [146] = 0 [147] = 0 [148] = 0 [149] = 0 [150] = 0 [151] = 0 [152] = 0 [153] = 0 [154] = 0 [155] = 0 [156] = 0 [157] = 0 [158] = 0 [159] = 0 [160] = 0 [161] = 0 [162] = 0 [163] = 0 [164] = 0 [165] = 0 [166] = 0 [167] = 0 [168] = 0 [169] = 0 [170] = 0 [171] = 0 [172] = 0 [173] = 0 [174] = 0 [175] = 0 [176] = 0 [177] = 0 [178] = 0 [179] = 0 [180] = 0 [181] = 0 [182] = 0 [183] = 0 [184] = 0 [185] = 0 [186] = 0 [187] = 0 [188] = 0 [189] = 0 [190] = 0 [191] = 0 [192] = 0 [193] = 0 [194] = 0 [195] = 0 [196] = 0 [197] = 0 [198] = 0 [199] = 0 [200] = 0 [201] = 0 [202] = 0 [203] = 0 [204] = 0 [205] = 0 [206] = 0 [207] = 0 [208] = 0 [209] = 0 [210] = 0 [211] = 0 [212] = 0 [213] = 0 [214] = 0 [215] = 0 [216] = 0 [217] = 0 [218] = 0 [219] = 0 [220] = 0 [221] = 0 [222] = 0 [223] = 0 [224] = 0 [225] = 0 [226] = 0 [227] = 0 [228] = 0 [229] = 0 [230] = 0 [231] = 0 [232] = 0 [233] = 0 [234] = 0 [235] = 0 [236] = 0 [237] = 0 [238] = 0 [239] = 0 [240] = 0 [241] = 0 [242] = 0 [243] = 0 [244] = 0 [245] = 0 [246] = 0 [247] = 0 [248] = 0 [249] = 0 [250] = 0 [251] = 0 [252] = 0 [253] = 0 [254] = 0 [255] = 0 } backupHeapIndex = 0 flags = 160 } ip = 0x00000000400520c1 stack = 0x00007ffff0de9818 newStack = 0x00007ffff0de95d0 scratch = 0x00007ffff0de9928 continuation = 0x0000000000000000 exceptionStackAdjustment = 0 exceptionOffset = 0 exceptionHandler = 0x0000000000000000 tailAddress = 0x0000000000000000 virtualCallTarget = 0x0000000000000000 virtualCallIndex = 0 heapImage = 0x0000000000000000 codeImage = 0x0000000000000000 thunkTable = 0x000055555575d3a8 dynamicTable = 0x0000000000000000 trace = 0x00007ffff0de9a20 reference = 0x0000000000000000 arch = 0x0000555555763250 transition = 0x0000000000000000 traceContext = 0x0000000000000000 stackLimit = 140737234377120 referenceFrame = 0x0000000000000000 methodLockIsClean = true } (lldb) frame variable *t->m->processor->dynamicTable (void *) *t->m->processor->dynamicTable = 0x000000004005adf0 ```.
From that we can see that
dynamicTable
was set by the rest of the code inaddDynamic
for thet->m->processor
, but this doesn't appear to have been copied over to thet->dynamicTable
field? I think it might be a simple case of a missing call toupdateDynamicTable(t, t);
or something like that?? That might be understating the problem, however.Example application that results in this crash: https://github.com/Poddster/avian_null_dynamicTable
That app is the smallest I can make it, though smaller examples might exist. Changing practically anything in this example app makes the problem disappear. (Infact using that information I've managed to make my original app not crash by working around the issue and accessing a class earlier than it normally would. This seems to "fix" the problem for me, though the underlying issue is obviously still present.)