Skip to content

Commit cd2f54b

Browse files
committed
[GR-33038] Fix wrong return value in LLVMScope.readMember.
PullRequest: graal/9508
2 parents f31feb8 + e915736 commit cd2f54b

File tree

9 files changed

+165
-46
lines changed

9 files changed

+165
-46
lines changed

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/LLVMScope.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
import com.oracle.truffle.llvm.runtime.except.LLVMIllegalSymbolIndexException;
4949
import com.oracle.truffle.llvm.runtime.except.LLVMLinkerException;
5050
import com.oracle.truffle.llvm.runtime.global.LLVMGlobal;
51-
import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer;
51+
import com.oracle.truffle.llvm.runtime.interop.LLVMDataEscapeNode.LLVMPointerDataEscapeNode;
5252
import com.oracle.truffle.llvm.runtime.pointer.LLVMPointer;
5353

5454
@ExportLibrary(InteropLibrary.class)
@@ -259,23 +259,21 @@ boolean isMemberReadable(@SuppressWarnings("unused") String name) {
259259
@ExportMessage
260260
Object readMember(String globalName,
261261
@Cached BranchProfile exception,
262+
@Cached LLVMPointerDataEscapeNode escape,
262263
@CachedLibrary("this") InteropLibrary self) throws UnknownIdentifierException {
263264

264265
if (contains(globalName)) {
265266
LLVMSymbol symbol = get(globalName);
266-
if (symbol != null && symbol.isFunction()) {
267+
if (symbol != null) {
267268
try {
268269
LLVMPointer value = LLVMContext.get(self).getSymbol(symbol);
269270
if (value != null) {
270-
return LLVMManagedPointer.cast(value).getObject();
271+
return escape.executeWithTarget(value);
271272
}
272273
} catch (LLVMLinkerException | LLVMIllegalSymbolIndexException e) {
273274
// fallthrough
274275
}
275-
exception.enter();
276-
throw UnknownIdentifierException.create(globalName);
277276
}
278-
return symbol;
279277
}
280278
exception.enter();
281279
throw UnknownIdentifierException.create(globalName);

sulong/projects/com.oracle.truffle.llvm.runtime/src/com/oracle/truffle/llvm/runtime/debug/debugexpr/nodes/DebugExprFunctionCallNode.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2019, 2021, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -43,6 +43,7 @@
4343
import com.oracle.truffle.llvm.runtime.debug.debugexpr.parser.DebugExprException;
4444
import com.oracle.truffle.llvm.runtime.debug.debugexpr.parser.DebugExprType;
4545
import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode;
46+
import com.oracle.truffle.llvm.runtime.pointer.LLVMManagedPointer;
4647
import com.oracle.truffle.llvm.runtime.types.Type;
4748

4849
public abstract class DebugExprFunctionCallNode extends LLVMExpressionNode {
@@ -64,24 +65,30 @@ public DebugExprFunctionCallNode(String functionName, List<DebugExpressionPair>
6465
@TruffleBoundary
6566
public DebugExprType getType() {
6667
InteropLibrary library = InteropLibrary.getFactory().getUncached();
67-
if (library.isMemberExisting(scope, functionName)) {
68+
if (library.isMemberReadable(scope, functionName)) {
6869
try {
6970
Object member = library.readMember(scope, functionName);
70-
try {
71+
if (LLVMManagedPointer.isInstance(member)) {
72+
LLVMManagedPointer pointer = LLVMManagedPointer.cast(member);
73+
if (pointer.getOffset() == 0) {
74+
member = pointer.getObject();
75+
}
76+
}
77+
if (member instanceof LLVMFunctionDescriptor) {
7178
LLVMFunctionDescriptor ldv = (LLVMFunctionDescriptor) member;
7279
Type returnType = ldv.getLLVMFunction().getType().getReturnType();
7380
DebugExprType t = DebugExprType.getTypeFromLLVMType(returnType);
7481
return t;
75-
} catch (ClassCastException e) {
82+
} else {
83+
throw DebugExprException.create(this, "variable %s does not point to a function", functionName);
7684
}
77-
throw DebugExprException.create(this, "no type found for function %s", functionName);
7885
} catch (UnsupportedMessageException e) {
7986
throw DebugExprException.create(this, "error while accessing function %s", functionName);
8087
} catch (UnknownIdentifierException e) {
81-
throw DebugExprException.symbolNotFound(this, functionName, null);
88+
// fallthrough
8289
}
8390
}
84-
throw DebugExprException.create(this, "no type found for function %s", functionName);
91+
throw DebugExprException.symbolNotFound(this, functionName, null);
8592
}
8693

8794
@Specialization
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
*
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without modification, are
7+
* permitted provided that the following conditions are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright notice, this list of
10+
* conditions and the following disclaimer.
11+
*
12+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of
13+
* conditions and the following disclaimer in the documentation and/or other materials provided
14+
* with the distribution.
15+
*
16+
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to
17+
* endorse or promote products derived from this software without specific prior written
18+
* permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
21+
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22+
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23+
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25+
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27+
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28+
* OF THE POSSIBILITY OF SUCH DAMAGE.
29+
*/
30+
#include <stdio.h>
31+
32+
int globalVar;
33+
34+
void globalFn() {
35+
}
36+
37+
__attribute__((constructor)) int start() {
38+
__builtin_debugtrap();
39+
return 0;
40+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#
2+
# Copyright (c) 2021, Oracle and/or its affiliates.
3+
#
4+
# All rights reserved.
5+
#
6+
# Redistribution and use in source and binary forms, with or without modification, are
7+
# permitted provided that the following conditions are met:
8+
#
9+
# 1. Redistributions of source code must retain the above copyright notice, this list of
10+
# conditions and the following disclaimer.
11+
#
12+
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of
13+
# conditions and the following disclaimer in the documentation and/or other materials provided
14+
# with the distribution.
15+
#
16+
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to
17+
# endorse or promote products derived from this software without specific prior written
18+
# permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
21+
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22+
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23+
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
25+
# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26+
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27+
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28+
# OF THE POSSIBILITY OF SUCH DAMAGE.
29+
#
30+
31+
BREAK 38 CONTINUE "start"
32+
TOP_SCOPE partial
33+
MEMBER any any "globalVar"
34+
MEMBER any any "globalFn"

sulong/tests/com.oracle.truffle.llvm.tests/src/com/oracle/truffle/llvm/tests/debug/LLVMDebugTest.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public static Collection<Object[]> getConfigurations() {
7777
}
7878
configs.put("testReenterArgsAndVals.c", new String[]{BC_O0, BC_MEM2REG});
7979
configs.put("testFunctionPointer.c", new String[]{BC_O0, BC_MEM2REG, BC_O1});
80+
configs.put("testGlobalVars.c", new String[]{BC_O0, BC_MEM2REG, BC_O1});
8081
configs.put("testLongDouble.cpp", new String[]{BC_O0, BC_MEM2REG});
8182
configs.put("testBitFields.cpp", new String[]{BC_O0, BC_MEM2REG});
8283
configs.put("testScopes.cpp", new String[]{BC_O0, BC_MEM2REG, BC_O1});

sulong/tests/com.oracle.truffle.llvm.tests/src/com/oracle/truffle/llvm/tests/debug/LLVMDebugTestBase.java

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -148,22 +148,31 @@ private static void assertValues(DebugScope scope, Map<String, LLVMDebugValue> e
148148
throw new AssertionError("Missing Scope!");
149149
}
150150

151-
int count = 0;
152-
for (DebugValue actual : scope.getDeclaredValues()) {
151+
for (Map.Entry<String, LLVMDebugValue> entry : expectedLocals.entrySet()) {
152+
final String name = entry.getKey();
153+
final LLVMDebugValue expected = entry.getValue();
153154

154-
final String name = actual.getName();
155-
final LLVMDebugValue expected = expectedLocals.get(actual.getName());
156-
157-
if (expected != null) {
155+
DebugValue actual = scope.getDeclaredValue(name);
156+
if (actual != null) {
158157
try {
159158
expected.check(actual);
160-
count++;
161159
} catch (Throwable t) {
162160
throw new AssertionError(String.format("Error in local %s", name), t);
163161
}
162+
} else {
163+
throw new AssertionError(String.format("Missing local %s", name));
164+
}
165+
}
166+
167+
if (!isPartialScope) {
168+
for (DebugValue actual : scope.getDeclaredValues()) {
164169

165-
} else if (!isPartialScope) {
166-
throw new AssertionError(String.format("Unexpected scope member: %s", name));
170+
final String name = actual.getName();
171+
final LLVMDebugValue expected = expectedLocals.get(actual.getName());
172+
173+
if (expected == null) {
174+
throw new AssertionError(String.format("Unexpected scope member: %s", name));
175+
}
167176
}
168177
}
169178

@@ -174,11 +183,8 @@ private static void assertValues(DebugScope scope, Map<String, LLVMDebugValue> e
174183
final LLVMDebugValue expected = expectedLocals.get(receiver.getName());
175184
if (expected != null) {
176185
expected.check(receiver);
177-
count++;
178186
}
179187
}
180-
181-
assertEquals("Unexpected number of scope variables", expectedLocals.size(), count);
182188
}
183189

184190
private static final class BreakInfo {
@@ -263,6 +269,11 @@ public void onSuspend(SuspendedEvent event) {
263269
assertValues(actualScope, expectedScope.getLocals(), expectedScope.isPartial());
264270
actualScope = actualScope.getParent();
265271
}
272+
if (bpr.getTopScope() != null) {
273+
StopRequest.Scope expectedScope = bpr.getTopScope();
274+
actualScope = event.getSession().getTopScope("llvm");
275+
assertValues(actualScope, expectedScope.getLocals(), expectedScope.isPartial());
276+
}
266277
} catch (Throwable t) {
267278
throw new AssertionError(String.format("Error in function %s on line %d", bpr.getFunctionName(), bpr.getLine()), t);
268279
}

sulong/tests/com.oracle.truffle.llvm.tests/src/com/oracle/truffle/llvm/tests/debug/LLVMDebugValue.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -72,8 +72,10 @@ boolean isBuggy() {
7272
}
7373

7474
void checkType(DebugValue value) {
75-
final String actualType = getActualType(value);
76-
assertEquals("Unexpected type!", expectedType, actualType);
75+
if (expectedType != null) {
76+
final String actualType = getActualType(value);
77+
assertEquals("Unexpected type!", expectedType, actualType);
78+
}
7779
}
7880

7981
void check(DebugValue actualValue) {
@@ -101,6 +103,8 @@ String getExpectedDisplayValue() {
101103

102104
@Override
103105
void checkValue(DebugValue value) {
106+
// Check whether we can actually get the value, but ignore what it is.
107+
value.toDisplayString();
104108
}
105109
}
106110

sulong/tests/com.oracle.truffle.llvm.tests/src/com/oracle/truffle/llvm/tests/debug/StopRequest.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -43,6 +43,8 @@ final class StopRequest implements Iterable<StopRequest.Scope> {
4343
private final int expectLine;
4444
private final boolean needsBreakPoint;
4545

46+
private Scope topScope = null;
47+
4648
StopRequest(ContinueStrategy nextAction, String functionName, int expectLine, boolean needsBreakPoint) {
4749
this.nextAction = nextAction;
4850
this.functionName = functionName;
@@ -88,6 +90,14 @@ public Iterator<Scope> iterator() {
8890
return scopes.iterator();
8991
}
9092

93+
public Scope getTopScope() {
94+
return topScope;
95+
}
96+
97+
public void setTopScope(Scope topScope) {
98+
this.topScope = topScope;
99+
}
100+
91101
static final class Scope {
92102

93103
private final Map<String, LLVMDebugValue> expectLocals;

sulong/tests/com.oracle.truffle.llvm.tests/src/com/oracle/truffle/llvm/tests/debug/Trace.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2018, 2021, Oracle and/or its affiliates.
33
*
44
* All rights reserved.
55
*
@@ -42,6 +42,7 @@
4242
final class Trace implements Iterable<StopRequest> {
4343

4444
static final String KEYWORD_OPEN_SCOPE = "OPEN_SCOPE";
45+
static final String KEYWORD_TOP_SCOPE = "TOP_SCOPE";
4546
static final String KEYWORD_SUSPEND = "SUSPEND";
4647
static final String KEYWORD_PARTIAL_SCOPE = "partial";
4748
static final String KEYWORD_STOP = "STOP";
@@ -151,21 +152,15 @@ public void accept(String line) {
151152
parseStop(true);
152153
break;
153154

154-
case KEYWORD_OPEN_SCOPE: {
155-
String scopeName = buffer.pollFirst(); // may be null
156-
String partialScope = buffer.pollFirst(); // often null
157-
if (structured != null || !parents.isEmpty() || request == null) {
158-
error();
159-
}
160-
if (KEYWORD_PARTIAL_SCOPE.equals(scopeName) && partialScope == null) {
161-
scopeName = null;
162-
partialScope = KEYWORD_PARTIAL_SCOPE;
163-
}
164-
boolean isPartialScope = KEYWORD_PARTIAL_SCOPE.equals(partialScope);
165-
scope = new StopRequest.Scope(scopeName, isPartialScope);
155+
case KEYWORD_OPEN_SCOPE:
156+
parseScope();
166157
request.addScope(scope);
167158
break;
168-
}
159+
160+
case KEYWORD_TOP_SCOPE:
161+
parseScope();
162+
request.setTopScope(scope);
163+
break;
169164

170165
case KEYWORD_MEMBER:
171166
parseMember();
@@ -196,6 +191,20 @@ public void accept(String line) {
196191
}
197192
}
198193

194+
private void parseScope() {
195+
String scopeName = buffer.pollFirst(); // may be null
196+
String partialScope = buffer.pollFirst(); // often null
197+
if (structured != null || !parents.isEmpty() || request == null) {
198+
error();
199+
}
200+
if (KEYWORD_PARTIAL_SCOPE.equals(scopeName) && partialScope == null) {
201+
scopeName = null;
202+
partialScope = KEYWORD_PARTIAL_SCOPE;
203+
}
204+
boolean isPartialScope = KEYWORD_PARTIAL_SCOPE.equals(partialScope);
205+
scope = new StopRequest.Scope(scopeName, isPartialScope);
206+
}
207+
199208
private void parseStop(boolean needsBreakPoint) {
200209
if (structured != null || !parents.isEmpty()) {
201210
error();
@@ -253,9 +262,14 @@ private boolean parseBugginess() {
253262
}
254263

255264
private void parseMember() {
256-
final String kind = nextToken();
257-
final String type = nextToken();
258-
final String name = nextToken();
265+
String kind = nextToken();
266+
String type = nextToken();
267+
String name = nextToken();
268+
269+
switch (type) {
270+
case Trace.KEYWORD_KIND_ANY:
271+
type = null;
272+
}
259273

260274
LLVMDebugValue dbgValue = null;
261275
switch (kind) {

0 commit comments

Comments
 (0)